Skip to content

Commit

Permalink
api benchmarks
Browse files Browse the repository at this point in the history
  • Loading branch information
jraymakers committed Aug 18, 2024
1 parent 771a214 commit 805f5d1
Show file tree
Hide file tree
Showing 12 changed files with 178 additions and 1 deletion.
4 changes: 3 additions & 1 deletion api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
"build:test": "tsc -b test",
"clean": "rimraf pkgs/@duckdb/node-api/lib",
"test": "vitest run",
"test:watch": "vitest"
"test:watch": "vitest",
"bench": "vitest bench --run",
"bench:watch": "vitest bench"
},
"dependencies": {
"@duckdb/node-bindings": "workspace:*"
Expand Down
9 changes: 9 additions & 0 deletions api/test/bench/types_bit.bench.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { bench, describe } from 'vitest';
import { benchFn, benchOpts } from './util/benchUtils';

describe('types (bit)', () => {
bench('bit (small)', benchFn(`select '101010'::bit from range(1000000)`), benchOpts());
bench('bit (short)', benchFn(`select bitstring('0101011', 11 * 8) from range(1000000)`), benchOpts());
bench('bit (short + 1 = smallest long)', benchFn(`select bitstring('0101011', 11 * 8 + 1) from range(1000000)`), benchOpts());
bench('bit (long)', benchFn(`select bitstring('0101011', 11 * 8 + 12 * 8) from range(1000000)`), benchOpts());
});
23 changes: 23 additions & 0 deletions api/test/bench/types_datetime.bench.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { bench, describe } from 'vitest';
import { benchFn, benchOpts } from './util/benchUtils';

describe('types (date)', () => {
bench('date', benchFn(`select '2123-12-31'::date from range(1000000)`), benchOpts());
});

describe('types (time)', () => {
bench('time', benchFn(`select '12:34:56.789123'::time from range(1000000)`), benchOpts());
bench('timetz', benchFn(`select '12:34:56-15:59:59'::timetz from range(1000000)`), benchOpts());
});

describe('types (timestamp)', () => {
bench('timestamp', benchFn(`select '2123-12-31 12:34:56.789123'::timestamp from range(1000000)`), benchOpts());
bench('timestamp_s', benchFn(`select '2123-12-31 12:34:56'::timestamp_s from range(1000000)`), benchOpts());
bench('timestamp_ms', benchFn(`select '2123-12-31 12:34:56.789'::timestamp_ms from range(1000000)`), benchOpts());
bench('timestamp_ns', benchFn(`select '2123-12-31 12:34:56.789123'::timestamp_ns from range(1000000)`), benchOpts());
bench('timestamptz', benchFn(`select '2123-12-31 12:34:56.789123'::timestamptz from range(1000000)`), benchOpts());
});

describe('types (interval)', () => {
bench('interval', benchFn('select interval 1 minute from range(1000000)'), benchOpts());
});
20 changes: 20 additions & 0 deletions api/test/bench/types_enum.bench.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { bench, describe } from 'vitest';
import { benchFn, benchOpts } from './util/benchUtils';

describe('types (enum)', () => {
bench('enum (small)', benchFn(`select 'a'::small_enum from range(1000000)`), benchOpts({
additionalSetup: async (connection) => {
await connection.run(`create type small_enum as enum ('a', 'b')`);
},
}));
bench('enum (medium)', benchFn(`select 'enum_0'::medium_enum from range(1000000)`), benchOpts({
additionalSetup: async (connection) => {
await connection.run(`create type medium_enum as enum (select 'enum_' || i from range(300) t(i))`);
}
}));
bench.skip('enum (large)', benchFn(`select 'enum_0'::large_enum from range(1000000)`), benchOpts({
additionalSetup: async (connection) => {
await connection.run(`create type large_enum as enum (select 'enum_' || i from range(70000) t(i))`);
}
}));
});
9 changes: 9 additions & 0 deletions api/test/bench/types_list.bench.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { bench, describe } from 'vitest';
import { benchFn, benchOpts } from './util/benchUtils';

describe('types (list & array)', () => {
bench('list[int]', benchFn('select [1] from range(1000000)'), benchOpts());
bench('list[varchar]', benchFn(`select ['a'] from range(1000000)`), benchOpts());
bench('array[int]', benchFn('select array_value(1) from range(1000000)'), benchOpts());
bench('array[varchar]', benchFn(`select array_value('a') from range(1000000)`), benchOpts());
});
14 changes: 14 additions & 0 deletions api/test/bench/types_misc.bench.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { bench, describe } from 'vitest';
import { benchFn, benchOpts } from './util/benchUtils';

describe('types (bool)', () => {
bench('bool', benchFn('select true from range(1000000)'), benchOpts());
});

describe('types (uuid)', () => {
bench('uuid', benchFn('select uuid() from range(1000000)'), benchOpts());
});

describe('types (union)', () => {
bench('union', benchFn(`select union_value(t := 'a') from range(1000000)`), benchOpts());
});
24 changes: 24 additions & 0 deletions api/test/bench/types_numeric.bench.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { bench, describe } from 'vitest';
import { benchFn, benchOpts } from './util/benchUtils';

describe('types (numeric)', () => {
bench('tinyint', benchFn('select 1::tinyint from range(1000000)'), benchOpts());
bench('smallint', benchFn('select 1::smallint from range(1000000)'), benchOpts());
bench('integer', benchFn('select 1::integer from range(1000000)'), benchOpts());
bench('bigint', benchFn('select 1::bigint from range(1000000)'), benchOpts());
bench('hugeint', benchFn('select 1::hugeint from range(1000000)'), benchOpts());

bench('utinyint', benchFn('select 1::utinyint from range(1000000)'), benchOpts());
bench('usmallint', benchFn('select 1::usmallint from range(1000000)'), benchOpts());
bench('uinteger', benchFn('select 1::uinteger from range(1000000)'), benchOpts());
bench('ubigint', benchFn('select 1::ubigint from range(1000000)'), benchOpts());
bench('uhugeint', benchFn('select 1::uhugeint from range(1000000)'), benchOpts());

bench('float', benchFn('select 1::float from range(1000000)'), benchOpts());
bench('double', benchFn('select 1::double from range(1000000)'), benchOpts());

bench('decimal (2 bytes)', benchFn('select 999.9::decimal(4,1) from range(1000000)'), benchOpts());
bench('decimal (4 bytes)', benchFn('select 99999.9999::decimal(9,4) from range(1000000)'), benchOpts());
bench('decimal (8 bytes)', benchFn('select 999999999999.999999::decimal(18,6) from range(1000000)'), benchOpts());
bench('decimal (16 bytes)', benchFn('select 9999999999999999999999999999.9999999999::decimal(38,10) from range(1000000)'), benchOpts());
});
9 changes: 9 additions & 0 deletions api/test/bench/types_struct.bench.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { bench, describe } from 'vitest';
import { benchFn, benchOpts } from './util/benchUtils';

describe('types (struct & map)', () => {
bench('struct[int]', benchFn('select {a:1} from range(1000000)'), benchOpts());
bench('struct[varchar]', benchFn(`select {a:'a'} from range(1000000)`), benchOpts());
bench('map[int,int]', benchFn('select map {1:1} from range(1000000)'), benchOpts());
bench('map[varchar,varchar]', benchFn(`select map {'a':'a'} from range(1000000)`), benchOpts());
});
9 changes: 9 additions & 0 deletions api/test/bench/types_varchar.bench.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { bench, describe } from 'vitest';
import { benchFn, benchOpts } from './util/benchUtils';

describe('types (varchar & blob)', () => {
bench('varchar (short)', benchFn(`select 'abcdefghijkl' from range(1000000)`), benchOpts());
bench('varchar (long)', benchFn(`select 'abcdefghijklmnopqrstuvwx' from range(1000000)`), benchOpts());
bench('blob (short)', benchFn(`select 'abcdefghijkl'::blob from range(1000000)`), benchOpts());
bench('blob (long)', benchFn(`select 'abcdefghijklmnopqrstuvwx'::blob from range(1000000)`), benchOpts());
});
31 changes: 31 additions & 0 deletions api/test/bench/util/benchUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { DuckDBConnection, DuckDBInstance } from '../../../src';
import { runSql } from './runSql';

let instance: DuckDBInstance;
let connection: DuckDBConnection;

async function setupConnection() {
instance = await DuckDBInstance.create();
connection = await instance.connect();
}

async function teardownConnection() {
await connection.dispose();
await instance.dispose();
}

export function benchFn(sql: string) {
return () => runSql(connection, sql);
}

export function benchOpts(options?: { additionalSetup?: (connection: DuckDBConnection) => Promise<void> }) {
const additionalSetup = options?.additionalSetup;
const setup = additionalSetup ? (
async () => {
await setupConnection();
await additionalSetup(connection);
}
) : setupConnection;
const teardown = teardownConnection;
return { setup, teardown };
}
21 changes: 21 additions & 0 deletions api/test/bench/util/runSql.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { DuckDBConnection } from '../../../src';

export async function runSql(connection: DuckDBConnection, sql: string): Promise<void> {
const result = await connection.run(sql);
let valueCount = 0;
let nullCount = 0;
let chunk = await result.fetchChunk();
while (chunk.rowCount > 0) {
const col0 = chunk.getColumn(0);
for (let i = 0; i < col0.itemCount; i++) {
if (col0.getItem(i) === null) {
nullCount++;
} else {
valueCount++;
}
}
chunk.dispose();
chunk = await result.fetchChunk();
}
chunk.dispose();
}
6 changes: 6 additions & 0 deletions api/test/bench/validity.bench.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { bench, describe } from 'vitest';
import { benchFn, benchOpts } from './util/benchUtils';

describe('validity', () => {
bench('odds null', benchFn('SELECT CASE WHEN range % 2 = 0 THEN range ELSE NULL END asdf FROM range(1000000)'), benchOpts());
});

0 comments on commit 805f5d1

Please sign in to comment.