This project provides a set of microbenchmarks to evaluate the performance of Go's built-in maps and various methods for iterating over strings, specifically for counting nucleotides and transcribing DNA to RNA. The benchmarks compare different approaches using byte and rune indexing, as well as array-based counting.
The goal is to measure and compare the efficiency of:
- Using Go maps with different key types (
byte,rune,int16) - Iterating over strings by byte index vs. rune range
- Counting nucleotides using arrays vs. maps
- Transcribing DNA to RNA using byte and rune slices
This is a microbenchmark-only project and does not provide any production-ready functionality.
The following functions are benchmarked (see main.go):
CountNucleotidesByByteIndexCountNucleotidesByByteIndexAsRuneCountNucleotidesByByteIndexAsInt16CountNucleotidesByRuneRangeCountNucleotidesArrayBytesCountNucleotidesArrayRunesTranscribeDnaToRnaBytesTranscribeDnaToRnaRunes
See main_test.go for the benchmark definitions.
To run all benchmarks with CPU profiling:
go test -bench=. -benchtime=1000000x -benchmem -cpuprofile=cpu.outTo generate a graph image of the CPU profile:
go tool pprof -png cpu.outBased on the microbenchmarks, the following conclusions can be drawn:
-
Byte vs. Rune Iteration: Iterating over strings by bytes is slightly faster than iterating by runes, provided the strings contain only ASCII characters. This is because byte iteration avoids the overhead of decoding runes.
-
Map Key Types and Performance: Maps with
bytekeys use the genericinternal/runtime/maps.(*Map).putSlotSmallmethod, which is significantly slower than the specializedinternal/runtime/maps.(*Map).putSlotSmallFast32method used for maps withint32keys (such asrune). As a result, usingruneas the map key can yield better performance than usingbyte. -
Array-Based Counting: When the set of possible keys is small and known in advance, using an array with direct indexing (for example, via a
switchstatement) is much faster than using a map. This approach eliminates hashing and lookup overhead. -
Type Conversion for Maps: If a map must be used, converting a small value (like a
byte) to a larger type (such as arune) can significantly improve performance due to the more efficient map implementation for larger key types.
These findings highlight the importance of choosing the right data structures and iteration methods for optimal performance in Go, especially when processing large strings or performing