Frontend Labs
⋯

Day 11 — Benchmarks & Examples

Learning Objectives

  • Write benchmarks to get real numbers, not intuitions
  • Compare implementations: map vs linear scan vs binary search
  • Read ns/op and allocs/op output to make data-driven decisions

Key Concepts

// Benchmark function signature — must start with Benchmark
func BenchmarkLookup(b *testing.B) {
    data := buildTestData(1000) // setup outside loop
    b.ResetTimer()              // don't count setup time

    for i := 0; i < b.N; i++ { // b.N is chosen by the framework
        _ = lookupLinear(data, "target")
    }
}

// Run: go test -bench=. -benchmem -benchtime=3s ./...
// Output:
// BenchmarkLookupLinear-8    5234891    229 ns/op    0 B/op    0 allocs/op
// BenchmarkLookupMap-8      78234512    15.3 ns/op   0 B/op    0 allocs/op

Exercise: Compare Lookup Strategies

// lookup_bench_test.go
package lookup_test

import (
    "sort"
    "testing"
)

// Linear scan: O(n) but simple
func lookupLinear(data []string, target string) bool {
    for _, s := range data {
        if s == target { return true }
    }
    return false
}

// Map: O(1) amortized, but higher memory
func lookupMap(data map[string]struct{}, target string) bool {
    _, ok := data[target]
    return ok
}

// Binary search: O(log n), sorted slice, good for static data
func lookupBinary(data []string, target string) bool {
    i := sort.SearchStrings(data, target)
    return i < len(data) && data[i] == target
}

func BenchmarkLookupLinear100(b *testing.B) {
    data := makeSlice(100)
    b.ResetTimer()
    for i := 0; i < b.N; i++ {
        lookupLinear(data, "item-099")
    }
}

func BenchmarkLookupMap100(b *testing.B) {
    data := makeMap(100)
    b.ResetTimer()
    for i := 0; i < b.N; i++ {
        lookupMap(data, "item-099")
    }
}

func BenchmarkLookupBinary100(b *testing.B) {
    data := makeSlice(100)
    sort.Strings(data)
    b.ResetTimer()
    for i := 0; i < b.N; i++ {
        lookupBinary(data, "item-099")
    }
}

Real-World Context

Your WAF's CIDR blocklist lookup runs on every request. At 10k rps, a 100ns lookup costs 1ms CPU per second. A 15ns map lookup costs 0.15ms. For static data (IP blocklist, API key allowlist), a pre-built map is the right choice. Binary search works for sorted CIDRs.


Generated from week2.md · 8 Oct 2026 16:36