Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 107 additions & 0 deletions benchmarks/sqlite_bench/sqlite_bench.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
// SQLite benchmark - C
// Tests: create table, insert, query, update, delete

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sqlite3.h>

int main(int argc, char *argv[]) {
int n = 1000;
if (argc > 1) {
n = atoi(argv[1]);
}

sqlite3 *db;
sqlite3_stmt *stmt;
char sql[256];
int rc;
long long total_score = 0;

// Use in-memory database for benchmarking
rc = sqlite3_open(":memory:", &db);
if (rc != SQLITE_OK) {
fprintf(stderr, "Cannot open database: %s\n", sqlite3_errmsg(db));
return 1;
}

// Create table
rc = sqlite3_exec(db, "CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, email TEXT, score INTEGER)", NULL, NULL, NULL);
if (rc != SQLITE_OK) {
fprintf(stderr, "SQL error: %s\n", sqlite3_errmsg(db));
sqlite3_close(db);
return 1;
}

// Begin transaction for inserts
sqlite3_exec(db, "BEGIN TRANSACTION", NULL, NULL, NULL);

// Prepare insert statement
rc = sqlite3_prepare_v2(db, "INSERT INTO users (name, email, score) VALUES (?, ?, ?)", -1, &stmt, NULL);
if (rc != SQLITE_OK) {
fprintf(stderr, "Prepare error: %s\n", sqlite3_errmsg(db));
sqlite3_close(db);
return 1;
}

// Insert N rows
char name[32], email[64];
for (int i = 0; i < n; i++) {
snprintf(name, sizeof(name), "user%d", i);
snprintf(email, sizeof(email), "user%d@example.com", i);

sqlite3_bind_text(stmt, 1, name, -1, SQLITE_TRANSIENT);
sqlite3_bind_text(stmt, 2, email, -1, SQLITE_TRANSIENT);
sqlite3_bind_int(stmt, 3, i * 10);

sqlite3_step(stmt);
sqlite3_reset(stmt);
}
sqlite3_finalize(stmt);

// Commit transaction
sqlite3_exec(db, "COMMIT", NULL, NULL, NULL);

// Query all rows
rc = sqlite3_prepare_v2(db, "SELECT * FROM users", -1, &stmt, NULL);
if (rc != SQLITE_OK) {
fprintf(stderr, "Query prepare error: %s\n", sqlite3_errmsg(db));
sqlite3_close(db);
return 1;
}

while (sqlite3_step(stmt) == SQLITE_ROW) {
total_score += sqlite3_column_int(stmt, 3);
}
sqlite3_finalize(stmt);

// Begin transaction for updates
sqlite3_exec(db, "BEGIN TRANSACTION", NULL, NULL, NULL);

// Prepare update statement
rc = sqlite3_prepare_v2(db, "UPDATE users SET score = score + 1 WHERE id = ?", -1, &stmt, NULL);
if (rc != SQLITE_OK) {
fprintf(stderr, "Update prepare error: %s\n", sqlite3_errmsg(db));
sqlite3_close(db);
return 1;
}

// Update all rows
for (int i = 0; i < n; i++) {
sqlite3_bind_int(stmt, 1, i + 1);
sqlite3_step(stmt);
sqlite3_reset(stmt);
}
sqlite3_finalize(stmt);

// Commit transaction
sqlite3_exec(db, "COMMIT", NULL, NULL, NULL);

// Delete all rows
sqlite3_exec(db, "DELETE FROM users", NULL, NULL, NULL);

sqlite3_close(db);

printf("%lld\n", total_score);
return 0;
}
63 changes: 63 additions & 0 deletions benchmarks/sqlite_bench/sqlite_bench.hml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// SQLite benchmark - Hemlock
// Tests: create table, insert, query, update, delete

import { open_db, exec, query, close_db, begin, commit } from "@stdlib/sqlite";

fn parse_int(s) {
let result = 0;
let i = 0;
while (i < s.length) {
let ch = s[i];
let code: i32 = ch;
let zero: i32 = '0';
result = result * 10 + (code - zero);
i = i + 1;
}
return result;
}

let n = 1000;
if (args.length > 1) {
n = parse_int(args[1]);
}

// Use in-memory database for benchmarking
let db = open_db(":memory:");

// Create table
exec(db, "CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, email TEXT, score INTEGER)");

// Insert N rows using transaction for performance
begin(db);
let i = 0;
while (i < n) {
exec(db, "INSERT INTO users (name, email, score) VALUES (?, ?, ?)",
["user" + i, "user" + i + "@example.com", i * 10]);
i = i + 1;
}
commit(db);

// Query all rows
let rows = query(db, "SELECT * FROM users");
let total_score = 0;
i = 0;
while (i < rows.length) {
total_score = total_score + rows[i].score;
i = i + 1;
}

// Update all rows
begin(db);
i = 0;
while (i < n) {
exec(db, "UPDATE users SET score = score + 1 WHERE id = ?", [i + 1]);
i = i + 1;
}
commit(db);

// Delete all rows
exec(db, "DELETE FROM users");

close_db(db);

print(total_score);
47 changes: 47 additions & 0 deletions benchmarks/sqlite_bench/sqlite_bench.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// SQLite benchmark - JavaScript (Node.js with better-sqlite3)
// Tests: create table, insert, query, update, delete

const Database = require('better-sqlite3');

const n = parseInt(process.argv[2]) || 1000;

// Use in-memory database for benchmarking
const db = new Database(':memory:');

// Create table
db.exec('CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, email TEXT, score INTEGER)');

// Insert N rows using transaction for performance
const insert = db.prepare('INSERT INTO users (name, email, score) VALUES (?, ?, ?)');
const insertMany = db.transaction((items) => {
for (const item of items) insert.run(item.name, item.email, item.score);
});

const items = [];
for (let i = 0; i < n; i++) {
items.push({ name: `user${i}`, email: `user${i}@example.com`, score: i * 10 });
}
insertMany(items);

// Query all rows
const rows = db.prepare('SELECT * FROM users').all();
let totalScore = 0;
for (const row of rows) {
totalScore += row.score;
}

// Update all rows
const update = db.prepare('UPDATE users SET score = score + 1 WHERE id = ?');
const updateMany = db.transaction(() => {
for (let i = 0; i < n; i++) {
update.run(i + 1);
}
});
updateMany();

// Delete all rows
db.exec('DELETE FROM users');

db.close();

console.log(totalScore);
41 changes: 41 additions & 0 deletions benchmarks/sqlite_bench/sqlite_bench.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#!/usr/bin/env python3
# SQLite benchmark - Python
# Tests: create table, insert, query, update, delete

import sqlite3
import sys

n = 1000
if len(sys.argv) > 1:
n = int(sys.argv[1])

# Use in-memory database for benchmarking
conn = sqlite3.connect(":memory:")
cursor = conn.cursor()

# Create table
cursor.execute("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, email TEXT, score INTEGER)")

# Insert N rows
for i in range(n):
cursor.execute("INSERT INTO users (name, email, score) VALUES (?, ?, ?)",
(f"user{i}", f"user{i}@example.com", i * 10))
conn.commit()

# Query all rows
cursor.execute("SELECT * FROM users")
rows = cursor.fetchall()
total_score = sum(row[3] for row in rows)

# Update all rows
for i in range(n):
cursor.execute("UPDATE users SET score = score + 1 WHERE id = ?", (i + 1,))
conn.commit()

# Delete all rows
cursor.execute("DELETE FROM users")
conn.commit()

conn.close()

print(total_score)
39 changes: 39 additions & 0 deletions benchmarks/sqlite_bench/sqlite_bench.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/usr/bin/env ruby
# SQLite benchmark - Ruby
# Tests: create table, insert, query, update, delete

require 'sqlite3'

n = (ARGV[0] || 1000).to_i

# Use in-memory database for benchmarking
db = SQLite3::Database.new(':memory:')

# Create table
db.execute('CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, email TEXT, score INTEGER)')

# Insert N rows using transaction for performance
db.transaction do
n.times do |i|
db.execute('INSERT INTO users (name, email, score) VALUES (?, ?, ?)',
["user#{i}", "user#{i}@example.com", i * 10])
end
end

# Query all rows
rows = db.execute('SELECT * FROM users')
total_score = rows.sum { |row| row[3] }

# Update all rows
db.transaction do
n.times do |i|
db.execute('UPDATE users SET score = score + 1 WHERE id = ?', [i + 1])
end
end

# Delete all rows
db.execute('DELETE FROM users')

db.close

puts total_score
11 changes: 8 additions & 3 deletions run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ usage() {
echo " --timeout N Timeout per iteration in seconds (default: 60)"
echo " --help, -h Show this help"
echo ""
echo "Benchmarks: fib, array_sum, string_concat, primes_sieve, quicksort, binary_tree, graph_bfs, json_serialize, json_deserialize, hash_sha256"
echo "Benchmarks: fib, array_sum, string_concat, primes_sieve, quicksort, binary_tree, graph_bfs, json_serialize, json_deserialize, hash_sha256, sqlite_bench"
echo " (leave empty to run all)"
}

Expand Down Expand Up @@ -94,6 +94,9 @@ get_input() {
hash_sha256)
[[ $QUICK_MODE -eq 1 ]] && echo 1000 || echo 10000
;;
sqlite_bench)
[[ $QUICK_MODE -eq 1 ]] && echo 100 || echo 1000
;;
esac
}

Expand Down Expand Up @@ -143,7 +146,9 @@ run_benchmark() {
local src="$bench_dir/${bench}.c"
local bin="$BUILD_DIR/${bench}_c"
[[ ! -f "$src" ]] && return 1
error_output=$(gcc -O3 -o "$bin" "$src" 2>&1)
local extra_libs=""
[[ "$bench" == "sqlite_bench" ]] && extra_libs="-lsqlite3"
error_output=$(gcc -O3 -o "$bin" "$src" $extra_libs 2>&1)
if [[ $? -ne 0 ]]; then
echo "ERROR:compile:$error_output"
return 2
Expand Down Expand Up @@ -301,7 +306,7 @@ run_all() {
if [[ -n "$BENCHMARK" ]]; then
benchmarks="$BENCHMARK"
else
benchmarks="fib array_sum string_concat primes_sieve quicksort binary_tree graph_bfs json_serialize json_deserialize hash_sha256"
benchmarks="fib array_sum string_concat primes_sieve quicksort binary_tree graph_bfs json_serialize json_deserialize hash_sha256 sqlite_bench"
fi

local languages="c hemlockc hemlock python javascript ruby"
Expand Down