A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://github.com/Lighter-swift/PerformanceTestSuite below:

Lighter-swift/PerformanceTestSuite: Repository containing code to evaluate the Lighter performance against other frameworks

Lighter Performance Test Suite

This repository contains code to test the Lighter performance. It uses the (populated) Northwind SQLite database as the base set. It doesn't have the goal to be scientifically proper.

It evaluates the load performance on queries against the "Orders" table, which has 16K records. The test loads all 16K records on each iteration.

Lighter is expected to perform excellent, as it directly/statically binds SQLite prepared statements for the generated structures.

M1 Mini with 10 rampup iterations and 500 test iterations.

Orders.fetchAll    setup    rampup   duration
  Enlighter SQLite 0        0,135s     6,629s   ~20% faster than Lighter (75/s)
  Lighter          0        0,162s     7,927s   Baseline                 (63/s)
  GRDB             -        -        ~12s       Handwritten Mapping
  SQLite.swift     0        0,613s    30,643s   Handwritten Mapping (>3× slower) (16/s)
  GRDB             0,001    0,995s    49,404s   Codable (>6× slower)     (10/s)
  SQLite.swift     0,001    3,109s   153,172s   Codable (>19× slower)    (3/s)

Essentially the specific testcase with no handcrafting involved needs 30 secs on GRDB, which is state of the art, 2.5 minutes w/ SQLite.swift and not about 8 secs with the Lighter API.

As a chart:

┌─────────────────────────────────────────────────────────────────────────────┐
├─┐                                                                           │
│S│                Enlighter generated raw SQLite API Bindings   ~20% faster  │
├─┘                                                                           │
├──┐                                                                          │
│L3│               Lighter, w/ high level API (baseline)            Baseline  │
├──┘                                                                          │
├─────┐                                                                       │
│GRDB │            with handwritten record mappings              ~50% slower  │
├─────┘                                                                       │
├─────────────┐                                                               │
│SQLite.swift │    with handwritten record mappings               >3× slower  │
├─────────────┘                                                               │
├───────────────────────┐                                                     │
│GRDB with Codable      │                                         >6× slower  │
├───────────────────────┘                                                     │
├───────────────────────────────────────────────────────────────────────────┐ │
│SQLite.swift with Codable                                       >19× slower│ │
├───────────────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
      Time to load the Northwind "Products" table 500 times into a model.      
                              Shorter is faster.                               

Main takeway: Never ever use Codable.

$ cd /tmp
$ git clone https://github.com/jpwhite3/northwind-SQLite3
$ cd northwind-SQLite3
$ make build populate
rm -rf ./dist
mkdir ./dist
sqlite3 dist/northwind.db < src/create.sql > /dev/null
sqlite3 dist/northwind.db < src/update.sql > /dev/null
sqlite3 dist/northwind.db < src/report.sql
Categories|8
CustomerCustomerDemo|0
CustomerDemographics|0
Customers|93
EmployeeTerritories|49
Employees|9
Details|2155
Orders|830
Products|77
Regions|4
Shippers|3
Suppliers|29
Territories|53
python3 ./src/populate.py
sqlite3 dist/northwind.db < src/report.sql
Categories|8
CustomerCustomerDemo|0
CustomerDemographics|0
Customers|93
EmployeeTerritories|49
Employees|9
Details|588936      <==
Orders|15889        <==
Products|77
Regions|4
Shippers|3
Suppliers|29
Territories|53

$ ls -lh dist
-rw-r--r--  1 helge  wheel    23M Aug  6 11:05 northwind.db

$ sqlite3 -readonly dist/northwind.db 
SQLite version 3.37.0 2021-12-09 01:34:53
sqlite> SELECT COUNT(*) FROM "Orders";
15889
sqlite> SELECT COUNT(*) FROM "Order Details";
588936
CREATE TABLE [Orders](
  [OrderID]        INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
  [CustomerID]     TEXT,
  [EmployeeID]     INTEGER,
  [OrderDate]      DATETIME, -- 2019-02-10 04:59:33
  [RequiredDate]   DATETIME,
  [ShippedDate]    DATETIME,
  [ShipVia]        INTEGER,
  [Freight]        NUMERIC DEFAULT 0,
  [ShipName]       TEXT,
  [ShipAddress]    TEXT,
  [ShipCity]       TEXT,
  [ShipRegion]     TEXT,
  [ShipPostalCode] TEXT,
  [ShipCountry]    TEXT,
  
  FOREIGN KEY ([EmployeeID]) 
    REFERENCES [Employees] ([EmployeeID]) 
      ON DELETE NO ACTION ON UPDATE NO ACTION,
  FOREIGN KEY ([CustomerID]) 
    REFERENCES [Customers] ([CustomerID]) 
      ON DELETE NO ACTION ON UPDATE NO ACTION,
  FOREIGN KEY ([ShipVia]) 
    REFERENCES [Shippers] ([ShipperID]) 
      ON DELETE NO ACTION ON UPDATE NO ACTION
);

CREATE TABLE [Order Details](
  [OrderID]   INTEGER NOT NULL,
  [ProductID] INTEGER NOT NULL,
  [UnitPrice] NUMERIC NOT NULL DEFAULT 0,
  [Quantity]  INTEGER NOT NULL DEFAULT 1,
  [Discount]  REAL    NOT NULL DEFAULT 0,
  
  PRIMARY KEY ("OrderID","ProductID"),
  CHECK ([Discount]>=(0) AND [Discount]<=(1)),
  CHECK ([Quantity]>(0)),
  CHECK ([UnitPrice]>=(0)),
  
  FOREIGN KEY ([OrderID]) 
    REFERENCES [Orders] ([OrderID]) 
      ON DELETE NO ACTION ON UPDATE NO ACTION,
  FOREIGN KEY ([ProductID]) 
    REFERENCES [Products] ([ProductID]) 
      ON DELETE NO ACTION ON UPDATE NO ACTION
);
$ cd /tmp
$ git clone https://github.com/groue/GRDB.swift
$ cd GRDB.swift/
$ git checkout v5.26.0
$ du -sh .
232M  .
$ pushd Tests/Performance/GRDBProfiling/GRDBProfiling
sqlite> .schema
CREATE TABLE items (i0 INT, i1 INT, i2 INT, i3 INT, i4 INT, i5 INT, i6 INT, i7 INT, i8 INT, i9 INT);
sqlite> SELECT COUNT(*) FROM items;
100000
$ curl https://bun.sh/install | bash
bun was installed successfully to ~/.bun/bin/bun 

Manually add the directory to ~/.zshrc (or similar):
  export BUN_INSTALL="$HOME/.bun" 
  export PATH="$BUN_INSTALL/bin:$PATH" 

$ bun --version
0.1.7
$ git clone https://github.com/oven-sh/bun.git
$ cd bun/bench/sqlite
$ bun query.js
cpu: unknown
runtime: bun 0.1.2 (arm64-darwin) 

benchmark                   time (avg)             (min … max)       p75       p99      p995
-------------------------------------------------------------- -----------------------------
SELECT * FROM "Orders"   13.04 ms/iter   (12.56 ms … 14.74 ms)  12.97 ms  14.74 ms  14.74 ms

That actually matches Lighter, it probably is the baseline SQLite3 performance with no mapping overheader (Lighter almost has zero, except for Swift String creation).

Presumably this doesn't include any garbage collection in bun, while the Swift tests free the records in each iteration via ARC.

Lighter is brought to you by Helge Heß / ZeeZide. We like feedback, GitHub stars, cool contract work, presumably any form of praise you can think of.

Want to support my work? Buy an app: Past for iChat, SVG Shaper, Shrugs, HMScriptEditor. You don't have to use it! 😀


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4