mirror of
				https://gitlab.com/cznic/sqlite.git
				synced 2025-11-04 02:28:41 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			111 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			111 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// Copyright 2021 The Sqlite Authors. All rights reserved.
 | 
						|
// Use of this source code is governed by a BSD-style
 | 
						|
// license that can be found in the LICENSE file.
 | 
						|
 | 
						|
// this file allows to run benchmarks via go test
 | 
						|
package benchmark
 | 
						|
 | 
						|
import (
 | 
						|
	"database/sql"
 | 
						|
	"flag"
 | 
						|
	"fmt"
 | 
						|
	"os"
 | 
						|
	"runtime"
 | 
						|
	"testing"
 | 
						|
 | 
						|
	"github.com/klauspost/cpuid/v2"
 | 
						|
	_ "github.com/mattn/go-sqlite3"
 | 
						|
	_ "modernc.org/sqlite"
 | 
						|
)
 | 
						|
 | 
						|
var (
 | 
						|
	// flag, allows to run each benchmark multiple times and average the results. this may provide more stable results between runs
 | 
						|
	reps uint
 | 
						|
 | 
						|
	// flag, whether to use in-memory SQLite
 | 
						|
	inMemory bool
 | 
						|
 | 
						|
	// benchmark funcs to execute
 | 
						|
	funcs = []func(*testing.B, *sql.DB){
 | 
						|
		benchCreateIndex,
 | 
						|
		benchSelectOnStringComparison,
 | 
						|
		benchSelectWithIndex,
 | 
						|
		benchSelectWithoutIndex,
 | 
						|
		benchInsert,
 | 
						|
		benchInsertInTransaction,
 | 
						|
		benchInsertIntoIndexed,
 | 
						|
		benchInsertFromSelect,
 | 
						|
		benchUpdateTextWithIndex,
 | 
						|
		benchUpdateWithIndex,
 | 
						|
		benchUpdateWithoutIndex,
 | 
						|
		benchDeleteWithoutIndex,
 | 
						|
		benchDeleteWithIndex,
 | 
						|
 | 
						|
		// due to very long run of this benchmark, it is disabled
 | 
						|
		// benchDropTable,
 | 
						|
	}
 | 
						|
)
 | 
						|
 | 
						|
func TestMain(m *testing.M) {
 | 
						|
	flag.UintVar(&reps, "rep", 1, "allows to run each benchmark multiple times and average the results. this may provide more stable results between runs")
 | 
						|
	flag.BoolVar(&inMemory, "mem", false, "if set, use in-memory SQLite")
 | 
						|
	flag.Parse()
 | 
						|
	os.Exit(m.Run())
 | 
						|
}
 | 
						|
 | 
						|
func TestBenchmarkSQLite(t *testing.T) {
 | 
						|
	// print info about CPU and OS
 | 
						|
	fmt.Println()
 | 
						|
	fmt.Printf("goos:   %s\n", runtime.GOOS)
 | 
						|
	fmt.Printf("goarch: %s\n", runtime.GOARCH)
 | 
						|
	if cpu := cpuid.CPU.BrandName; cpu != "" {
 | 
						|
		fmt.Printf("cpu:    %s\n", cpu)
 | 
						|
	}
 | 
						|
	fmt.Printf("repeat: %d time(s)\n", reps)
 | 
						|
	fmt.Printf("in-memory SQLite: %v\n", inMemory)
 | 
						|
	fmt.Println()
 | 
						|
 | 
						|
	// loop on functions
 | 
						|
	for _, f := range funcs {
 | 
						|
 | 
						|
		var (
 | 
						|
			nsPerOpCGo    avgVal
 | 
						|
			nsPerOpPureGo avgVal
 | 
						|
		)
 | 
						|
 | 
						|
		// run benchmark against different drivers
 | 
						|
		for r := uint(0); r < reps; r++ {
 | 
						|
			// -- run bench against Cgo --
 | 
						|
			db := createDB(t, inMemory, "sqlite3")
 | 
						|
			br := testing.Benchmark(func(b *testing.B) { f(b, db) })
 | 
						|
 | 
						|
			// contribue metric to average
 | 
						|
			nsPerOpCGo.contribInt(br.NsPerOp())
 | 
						|
 | 
						|
			// close DB
 | 
						|
			if err := db.Close(); err != nil {
 | 
						|
				t.Fatal(err)
 | 
						|
			}
 | 
						|
 | 
						|
			// -- run bench against Pure-go --
 | 
						|
			db = createDB(t, inMemory, "sqlite")
 | 
						|
			br = testing.Benchmark(func(b *testing.B) { f(b, db) })
 | 
						|
 | 
						|
			// contribue metric to average
 | 
						|
			nsPerOpPureGo.contribInt(br.NsPerOp())
 | 
						|
			// close DB
 | 
						|
			if err := db.Close(); err != nil {
 | 
						|
				t.Fatal(err)
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		// print result row
 | 
						|
		fmt.Printf("%-35s | %5.2fx | CGo: %7.3f ms/op | Pure-Go: %7.3f ms/op\n",
 | 
						|
			toSnakeCase(getFuncName(f)),
 | 
						|
			nsPerOpPureGo.val/nsPerOpCGo.val, // factor
 | 
						|
			nsPerOpCGo.val/1e6,               // ms/op
 | 
						|
			nsPerOpPureGo.val/1e6,            // ms/op
 | 
						|
		)
 | 
						|
	}
 | 
						|
}
 |