-
Notifications
You must be signed in to change notification settings - Fork 47
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Benchmarks of various Cid types as map keys.
And writeup on same. tl;dr interfaces are not cheap if you're already at the scale where you started caring about whether or not you have pointers.
- Loading branch information
Showing
3 changed files
with
93 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
package cid | ||
|
||
import ( | ||
"testing" | ||
) | ||
|
||
// BenchmarkCidMap_CidStr estimates how fast it is to insert primitives into a map | ||
// keyed by CidStr (concretely). | ||
// | ||
// We do 100 insertions per benchmark run to make sure the map initialization | ||
// doesn't dominate the results. | ||
// | ||
// Sample results on linux amd64 go1.11beta: | ||
// | ||
// BenchmarkCidMap_CidStr-8 100000 16317 ns/op | ||
// BenchmarkCidMap_CidIface-8 100000 20516 ns/op | ||
// | ||
// With benchmem on: | ||
// | ||
// BenchmarkCidMap_CidStr-8 100000 15579 ns/op 11223 B/op 207 allocs/op | ||
// BenchmarkCidMap_CidIface-8 100000 19500 ns/op 12824 B/op 307 allocs/op | ||
// BenchmarkCidMap_StrPlusHax-8 200000 10451 ns/op 7589 B/op 202 allocs/op | ||
// | ||
// We can see here that the impact of interface boxing is significant: | ||
// it increases the time taken to do the inserts to 133%, largely because | ||
// the implied `runtime.convT2E` calls cause another malloc each. | ||
// | ||
// There are also significant allocations in both cases because | ||
// A) we cannot create a multihash without allocations since they are []byte; | ||
// B) the map has to be grown several times; | ||
// C) something I haven't quite put my finger on yet. | ||
// Ideally we'd drive those down further as well. | ||
// | ||
// Pre-allocating the map reduces allocs by a very small percentage by *count*, | ||
// but reduces the time taken by 66% overall (presumably because when a map | ||
// re-arranges itself, it involves more or less an O(n) copy of the content | ||
// in addition to the alloc itself). This isn't topical to the question of | ||
// whether or not interfaces are a good idea; just for contextualizing. | ||
// | ||
func BenchmarkCidMap_CidStr(b *testing.B) { | ||
for i := 0; i < b.N; i++ { | ||
mp := map[CidStr]int{} | ||
for x := 0; x < 100; x++ { | ||
mp[NewCidStr(0, uint64(x), []byte{})] = x | ||
} | ||
} | ||
} | ||
|
||
// BenchmarkCidMap_CidIface is in the family of BenchmarkCidMap_CidStr: | ||
// it is identical except the map key type is declared as an interface | ||
// (which forces all insertions to be boxed, changing performance). | ||
func BenchmarkCidMap_CidIface(b *testing.B) { | ||
for i := 0; i < b.N; i++ { | ||
mp := map[Cid]int{} | ||
for x := 0; x < 100; x++ { | ||
mp[NewCidStr(0, uint64(x), []byte{})] = x | ||
} | ||
} | ||
} | ||
|
||
// BenchmarkCidMap_CidStrAvoidMapGrowth is in the family of BenchmarkCidMap_CidStr: | ||
// it is identical except the map is created with a size hint that removes | ||
// some allocations (5, in practice, apparently). | ||
func BenchmarkCidMap_CidStrAvoidMapGrowth(b *testing.B) { | ||
for i := 0; i < b.N; i++ { | ||
mp := make(map[CidStr]int, 100) | ||
for x := 0; x < 100; x++ { | ||
mp[NewCidStr(0, uint64(x), []byte{})] = x | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters