package maplab import ( "runtime" "testing" ) // --- Experiment 6: iteration start is randomized ---------------------------- func TestIterationOrder(t *testing.T) { m := make(map[int]int, 128) for i := 0; i < 128; i++ { m[i] = i } seen := map[int]bool{} for i := 0; i < 16; i++ { seen[FirstKey(m)] = true } if len(seen) < 2 { t.Fatalf("iteration start looks fixed: same first key across 16 ranges") } t.Logf("first key took %d distinct values across 16 ranges (randomized start)", len(seen)) } // --- Experiments 1 & 5: delete/clear retain memory; dropping frees it ------- func liveHeap() int64 { runtime.GC() var m runtime.MemStats runtime.ReadMemStats(&m) return int64(m.HeapAlloc) } func TestMapRetention(t *testing.T) { base := liveHeap() m := FilledMap() filled := liveHeap() - base DeleteAll(m) afterDelete := liveHeap() - base runtime.KeepAlive(m) m = nil // drop the table; now it can be collected _ = m afterDrop := liveHeap() - base t.Logf("filled +%4d MiB", filled>>20) t.Logf("after delete +%4d MiB (retained)", afterDelete>>20) t.Logf("after drop +%4d MiB", afterDrop>>20) if afterDelete < filled/2 { t.Fatalf("delete unexpectedly returned memory: filled=%d afterDelete=%d", filled, afterDelete) } if afterDrop > filled/2 { t.Fatalf("dropping the map did not return memory: afterDrop=%d", afterDrop) } } // --- Experiment 2: clear vs delete-loop (refill untimed) -------------------- const clearN = 100_000 func refill(m map[int]int) { for i := 0; i < clearN; i++ { m[i] = i } } func BenchmarkClear(b *testing.B) { m := make(map[int]int, clearN) refill(m) b.ResetTimer() for n := 0; n < b.N; n++ { clear(m) b.StopTimer() refill(m) b.StartTimer() } } func BenchmarkDeleteLoop(b *testing.B) { m := make(map[int]int, clearN) refill(m) b.ResetTimer() for n := 0; n < b.N; n++ { DeleteLoop(m) b.StopTimer() refill(m) b.StartTimer() } } // --- Experiment 4: pre-sizing ------------------------------------------------ var mapSink map[int]int func BenchmarkInsertNoPresize(b *testing.B) { for b.Loop() { mapSink = InsertNoPresize(clearN) } } func BenchmarkInsertPresize(b *testing.B) { for b.Loop() { mapSink = InsertPresize(clearN) } } // --- Experiment 3: lookups --------------------------------------------------- var ( bigMap = FilledMap() keys = lookupKeys(1000) intSink int ) func lookupKeys(count int) []int { ks := make([]int, count) stride := N / count for i := range ks { ks[i] = i * stride // spread across the table, all present } return ks } func BenchmarkLookup(b *testing.B) { for b.Loop() { intSink = LookupSum(bigMap, keys) } }