Skip to content

Instantly share code, notes, and snippets.

View benhoyt's full-sized avatar

Ben Hoyt benhoyt

View GitHub Profile
@benhoyt
benhoyt / markov.py
Created November 11, 2023 15:45
Generate text from an input using a simple Markov chain generator
import collections, random, sys, textwrap
# Build possibles table indexed by pair of prefix words (w1, w2)
w1 = w2 = ''
possibles = collections.defaultdict(list)
for line in sys.stdin:
for word in line.split():
possibles[w1, w2].append(word)
w1, w2 = w2, word
@benhoyt
benhoyt / count_features.py
Last active September 20, 2025 03:49
Go vs Python features added over time
# $ python3 count_features.py writings/go-python-features.md
# go1.25 0 23
# go1.24 1 29
# go1.23 15 27
# go1.22 6 41
# go1.21 8 50
# go1.20 4 33
# go1.19 0 14
# go1.18 15 31
# go1.17 3 15
@benhoyt
benhoyt / glob.go
Created June 8, 2022 01:25
Simple glob matcher in Go
package main
import (
"fmt"
"os"
"path/filepath"
)
func main() {
if len(os.Args) != 2 {
@benhoyt
benhoyt / mt.py
Created September 21, 2021 03:33
Quick performance test of Python 3.10's "match" vs "if...elif"
"""Quick performance tests comparing "match" with "if...elif".
See:
https://benhoyt.com/writings/python-pattern-matching/
https://news.ycombinator.com/item?id=28601616
# Enum switch with match:
$ python3.10 -m timeit -s 'import mt' -c 'mt.enum_match(mt.FileType.FILE)'
1000000 loops, best of 5: 356 nsec per loop
$ python3.10 -m timeit -s 'import mt' -c 'mt.enum_match(mt.FileType.SYMLINK)'
@benhoyt
benhoyt / ngrams.py
Created May 12, 2016 15:34
Print most frequent N-grams in given file
"""Print most frequent N-grams in given file.
Usage: python ngrams.py filename
Problem description: Build a tool which receives a corpus of text,
analyses it and reports the top 10 most frequent bigrams, trigrams,
four-grams (i.e. most frequently occurring two, three and four word
consecutive combinations).
NOTES
@benhoyt
benhoyt / atomic_counter.py
Created August 3, 2016 13:12
An atomic, thread-safe incrementing counter for Python
"""An atomic, thread-safe incrementing counter."""
import threading
class AtomicCounter:
"""An atomic, thread-safe incrementing counter.
>>> counter = AtomicCounter()
>>> counter.increment()
@benhoyt
benhoyt / goversions.py
Created April 13, 2024 04:53
Measure Go version performance with GoAWK
import csv
import os
import subprocess
import time
print('| Go version | binary size (MB) | countwords (s) | sumloop (s) |')
print('| ---------- | ---------------- | -------------- | ----------- |')
@benhoyt
benhoyt / goversions.txt
Created April 13, 2024 04:54
Go version performance - table of results
| Go version | binary size (MB) | countwords (s) | sumloop (s) |
| ---------- | ---------------- | -------------- | ----------- |
| 1.0 | 3.27 | 8.20 | 9.47 |
| 1.1 | 3.95 | 7.57 | 9.54 |
| 1.2 | 5.50 | 25.51 | 9.36 |
| 1.3 | 4.27 | 2.85 | 1.99 |
| 1.4 | 4.32 | 3.03 | 2.13 |
| 1.5 | 4.73 | 2.16 | 1.16 |
| 1.6 | 4.70 | 2.15 | 1.18 |
| 1.7 | 3.94 | 1.86 | 0.63 |
@benhoyt
benhoyt / gist:4044946
Created November 9, 2012 09:59
Speed up os.walk() significantly by using file attributes from FindFirst/Next or readdir
"""Speed up os.walk() significantly by using file attributes that
FindFirst/Next give us instead of doing an extra stat(). Can also do the same
thing with opendir/readdir on Linux.
This is doubly useful when the user (caller of os.walk) is doing *another*
stat() to get say the file sizes.
On my tests (Windows 64-bit) our walk() is about 5x as fast as os.walk() for
large directory trees, and 9x as fast if you're doing the file size thing.
Note that these timings are "once it's in the cache", not first-time timings.
@benhoyt
benhoyt / sliding_window_sort.py
Created February 22, 2017 20:49
Efficient sliding-window sorting of time-series data in CSV file (in Python)
"""Efficient sliding-window sorting of time-series data in CSV file.
Demo for http://stackoverflow.com/a/42398981/68707
Tested on Python 3.5.
"""
import collections
import csv
import datetime