<commit_before>// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Compare ptrie with map[string]interface{}.
// The benchmark was executed on random 16 byte keys.
//
// Results (v23 go test v.io/x/ref/services/syncbase/store/ptrie -bench . -benchtime 0.1s -run Benchmark):
// map:
// BenchmarkMapPut-12        	 1000000	       655 ns/op
// BenchmarkMapOverwrite-12  	 1000000	       186 ns/op
// BenchmarkMapDelete-12     	 1000000	       111 ns/op
// BenchmarkMapGet-12        	 2000000	        91.5 ns/op
// BenchmarkMapScan-12       	10000000	        19.9 ns/op
//
// ptrie with copyOnWrite = false
// BenchmarkPtriePut-12      	  200000	      1742 ns/op
// BenchmarkPtrieOverwrite-12	  200000	      1596 ns/op
// BenchmarkPtrieDelete-12   	  200000	      1557 ns/op
// BenchmarkPtrieGet-12      	  300000	      1473 ns/op
// BenchmarkPtrieScan-12     	  300000	       940 ns/op
//
// ptrie with copyOnWrite = true
// BenchmarkPtriePut-12      	   50000	      4026 ns/op
// BenchmarkPtrieOverwrite-12	   50000	      4015 ns/op
// BenchmarkPtrieDelete-12   	   50000	      3367 ns/op
// BenchmarkPtrieGet-12      	  300000	      1207 ns/op
// BenchmarkPtrieScan-12     	  200000	       879 ns/op
package ptrie

import (
	"math/rand"
	"testing"
)

const (
	keyLength   = 16
	seed        = 23917
	copyOnWrite = false
)

func randomKey(r *rand.Rand) []byte {
	key := make([]byte, keyLength)
	for i := 0; i < keyLength; i++ {
		key[i] = byte(r.Intn(256))
	}
	return key
}

func generatePtrieKeys(b *testing.B) [][]byte {
	keys := make([][]byte, b.N)
	r := rand.New(rand.NewSource(seed))
	for i := 0; i < b.N; i++ {
		keys[i] = randomKey(r)
	}
	return keys
}

func generateMapKeys(b *testing.B) []string {
	keys := make([]string, b.N)
	r := rand.New(rand.NewSource(seed))
	for i := 0; i < b.N; i++ {
		keys[i] = string(randomKey(r))
	}
	return keys
}

func fillPtrie(b *testing.B, t *T, keys [][]byte) {
	for i := 0; i < b.N; i++ {
		t.Put(keys[i], true)
	}
}

func fillMap(b *testing.B, m map[string]interface{}, keys []string) {
	for i := 0; i < b.N; i++ {
		m[keys[i]] = true
	}
}

func BenchmarkPtriePut(b *testing.B) {
	keys := generatePtrieKeys(b)
	t := New(copyOnWrite)
	b.ResetTimer()
	fillPtrie(b, t, keys)
}

func BenchmarkMapPut(b *testing.B) {
	keys := generateMapKeys(b)
	m := make(map[string]interface{})
	b.ResetTimer()
	fillMap(b, m, keys)
}

func BenchmarkPtrieOverwrite(b *testing.B) {
	keys := generatePtrieKeys(b)
	t := New(copyOnWrite)
	fillPtrie(b, t, keys)
	b.ResetTimer()
	fillPtrie(b, t, keys)
}

func BenchmarkMapOverwrite(b *testing.B) {
	keys := generateMapKeys(b)
	m := make(map[string]interface{})
	fillMap(b, m, keys)
	b.ResetTimer()
	fillMap(b, m, keys)
}

func BenchmarkPtrieDelete(b *testing.B) {
	keys := generatePtrieKeys(b)
	t := New(copyOnWrite)
	fillPtrie(b, t, keys)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		t.Delete(keys[i])
	}
}

func BenchmarkMapDelete(b *testing.B) {
	keys := generateMapKeys(b)
	m := make(map[string]interface{})
	fillMap(b, m, keys)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		delete(m, keys[i])
	}
}

func BenchmarkPtrieGet(b *testing.B) {
	keys := generatePtrieKeys(b)
	t := New(copyOnWrite)
	fillPtrie(b, t, keys)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		_ = t.Get(keys[i])
	}
}

func BenchmarkMapGet(b *testing.B) {
	keys := generateMapKeys(b)
	m := make(map[string]interface{})
	fillMap(b, m, keys)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		_ = m[keys[i]]
	}
}

func BenchmarkPtrieScan(b *testing.B) {
	keys := generatePtrieKeys(b)
	t := New(copyOnWrite)
	fillPtrie(b, t, keys)
	b.ResetTimer()
	s := t.Scan(nil, nil)
	for i := 0; i < b.N; i++ {
		s.Advance()
	}
	if s.Advance() {
		panic(123)
	}
}

func BenchmarkMapScan(b *testing.B) {
	keys := generateMapKeys(b)
	m := make(map[string]interface{})
	fillMap(b, m, keys)
	b.ResetTimer()
	for _, _ = range m {
	}
}<commit_msg>syncbase/store/ptrie/bench: reorder functions and skip map tests<commit_after>// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Compare ptrie with map[string]interface{}.
// The benchmark was executed on random 16 byte keys.
//
// Results (v23 go test v.io/x/ref/services/syncbase/store/ptrie -bench . -benchtime 0.1s -run Benchmark):
// map:
// BenchmarkMapPut-12        	 1000000	       655 ns/op
// BenchmarkMapOverwrite-12  	 1000000	       186 ns/op
// BenchmarkMapDelete-12     	 1000000	       111 ns/op
// BenchmarkMapGet-12        	 2000000	        91.5 ns/op
// BenchmarkMapScan-12       	10000000	        19.9 ns/op
//
// ptrie with copyOnWrite = false
// BenchmarkPtriePut-12      	  200000	      1742 ns/op
// BenchmarkPtrieOverwrite-12	  200000	      1596 ns/op
// BenchmarkPtrieDelete-12   	  200000	      1557 ns/op
// BenchmarkPtrieGet-12      	  300000	      1473 ns/op
// BenchmarkPtrieScan-12     	  300000	       940 ns/op
//
// ptrie with copyOnWrite = true
// BenchmarkPtriePut-12      	   50000	      4026 ns/op
// BenchmarkPtrieOverwrite-12	   50000	      4015 ns/op
// BenchmarkPtrieDelete-12   	   50000	      3367 ns/op
// BenchmarkPtrieGet-12      	  300000	      1207 ns/op
// BenchmarkPtrieScan-12     	  200000	       879 ns/op
package ptrie

import (
	"math/rand"
	"testing"
)

const (
	keyLength   = 16
	seed        = 23917
	copyOnWrite = false
)

func randomKey(r *rand.Rand) []byte {
	key := make([]byte, keyLength)
	for i := 0; i < keyLength; i++ {
		key[i] = byte(r.Intn(256))
	}
	return key
}

func generatePtrieKeys(b *testing.B) [][]byte {
	keys := make([][]byte, b.N)
	r := rand.New(rand.NewSource(seed))
	for i := 0; i < b.N; i++ {
		keys[i] = randomKey(r)
	}
	return keys
}

func generateMapKeys(b *testing.B) []string {
	keys := make([]string, b.N)
	r := rand.New(rand.NewSource(seed))
	for i := 0; i < b.N; i++ {
		keys[i] = string(randomKey(r))
	}
	return keys
}

func fillPtrie(b *testing.B, t *T, keys [][]byte) {
	for i := 0; i < b.N; i++ {
		t.Put(keys[i], true)
	}
}

func fillMap(b *testing.B, m map[string]interface{}, keys []string) {
	for i := 0; i < b.N; i++ {
		m[keys[i]] = true
	}
}

func BenchmarkPtriePut(b *testing.B) {
	keys := generatePtrieKeys(b)
	t := New(copyOnWrite)
	b.ResetTimer()
	fillPtrie(b, t, keys)
}

func BenchmarkPtrieOverwrite(b *testing.B) {
	keys := generatePtrieKeys(b)
	t := New(copyOnWrite)
	fillPtrie(b, t, keys)
	b.ResetTimer()
	fillPtrie(b, t, keys)
}

func BenchmarkPtrieDelete(b *testing.B) {
	keys := generatePtrieKeys(b)
	t := New(copyOnWrite)
	fillPtrie(b, t, keys)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		t.Delete(keys[i])
	}
}

func BenchmarkPtrieGet(b *testing.B) {
	keys := generatePtrieKeys(b)
	t := New(copyOnWrite)
	fillPtrie(b, t, keys)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		_ = t.Get(keys[i])
	}
}

func BenchmarkPtrieScan(b *testing.B) {
	keys := generatePtrieKeys(b)
	t := New(copyOnWrite)
	fillPtrie(b, t, keys)
	b.ResetTimer()
	s := t.Scan(nil, nil)
	for i := 0; i < b.N; i++ {
		s.Advance()
	}
}

func BenchmarkMapPut(b *testing.B) {
	// Running this test takes a lot of time and benchmarking a map is not
	// really important, so we skip the test.
	b.SkipNow()
	keys := generateMapKeys(b)
	m := make(map[string]interface{})
	b.ResetTimer()
	fillMap(b, m, keys)
}

func BenchmarkMapOverwrite(b *testing.B) {
	// Running this test takes a lot of time and benchmarking a map is not
	// really important, so we skip the test.
	b.SkipNow()
	keys := generateMapKeys(b)
	m := make(map[string]interface{})
	fillMap(b, m, keys)
	b.ResetTimer()
	fillMap(b, m, keys)
}

func BenchmarkMapDelete(b *testing.B) {
	// Running this test takes a lot of time and benchmarking a map is not
	// really important, so we skip the test.
	b.SkipNow()
	keys := generateMapKeys(b)
	m := make(map[string]interface{})
	fillMap(b, m, keys)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		delete(m, keys[i])
	}
}

func BenchmarkMapGet(b *testing.B) {
	// Running this test takes a lot of time and benchmarking a map is not
	// really important, so we skip the test.
	b.SkipNow()
	keys := generateMapKeys(b)
	m := make(map[string]interface{})
	fillMap(b, m, keys)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		_ = m[keys[i]]
	}
}

func BenchmarkMapScan(b *testing.B) {
	// Running this test takes a lot of time and benchmarking a map is not
	// really important, so we skip the test.
	b.SkipNow()
	keys := generateMapKeys(b)
	m := make(map[string]interface{})
	fillMap(b, m, keys)
	b.ResetTimer()
	for _, _ = range m {
	}
}
{'fraction_non_alphanumeric': 0.15177222545031957, 'fraction_numerical': 0.04822777454968042, 'mean_word_length': 2.9713890170742965, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 2, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '126929', 'n_tokens_mistral': 3788, 'n_tokens_neox': 3420, 'n_words': 869}