Saltar al contenido principal
Version: 0.12.0

Benchmarks

These numbers come from a reproducible go test -bench harness that lives in benchmarks/ in the repository. It measures Quark's per-operation overhead against a hand-written database/sql baseline and against GORM, on the same model, schema, data, and operations.

Microbenchmarks, not production timings

The harness runs against in-memory SQLite so it isolates ORM and driver CPU/allocation overhead, not disk or network I/O. Against a networked database, that overhead is a small fraction of round-trip latency — do not read these microseconds as production request times. Numbers are also machine- and run-specific: treat the relative ratios as the signal and reproduce locally before drawing conclusions.

What is measured

Five operations, chosen because they exercise the reflect-based hot paths (row scanning, insert/update building) that Quark's planned code generation will replace:

BenchmarkOperation
InsertOneInsert a single row
InsertBatchInsert 100 rows in one batch
FindByPKSelect one row by primary key
ListWhereSelect up to 50 rows with a WHERE age >= ? filter
UpdateUpdate one row (all non-PK columns) by primary key

Each is implemented three ways against the same bench_users table: hand-written database/sql (the floor), Quark's quark.For[T] API, and GORM (the reflect-ORM peer).

How to reproduce

cd benchmarks
go test -run=^$ -bench=. -benchmem ./...

See the harness README for the full methodology, its limits, and how to add another ORM.

A representative run

Apple M4 Pro, macOS, go1.26.0 toolchain, modernc.org/sqlite v1.23.1, gorm.io/gorm v1.31.0, in-memory SQLite. One -bench=. -benchmem run:

OperationRaw ns/opQuark ns/opGORM ns/opRaw allocsQuark allocsGORM allocs
InsertOne6,03812,29321,212206278
InsertBatch170,776258,973270,6016221,2771,287
FindByPK7,31115,54111,002246566
ListWhere(50)38,60471,17250,134365474705
Update3,0594,9639,132156284

Reading the numbers

  • Quark's reflect path runs about 1.5–2.1× the hand-written database/sql floor on these operations. That gap is the overhead the planned generated path is meant to recover — and it bounds it, since generated code cannot beat hand-written SQL.
  • Quark and GORM are in the same performance class. Neither dominates: in this run Quark is faster on inserts and updates, GORM is faster on the single-row read and the filtered list.
  • The reflection cache means model metadata is parsed once per type and reused; the remaining per-row cost is field-level reflection on scan and bind, which is what generated code removes.

Quark is not yet a v1.0 release and these results are not a claim of fastest-in-class. They exist to give an honest baseline that the code generation work will be measured against.