5WBYLJAC3MP52G4F5KHVTXOGCBYS7RFACMFQEAAA2D2TON4OBAGQC
NKL44S6YUCLZDH5EDDUJB5BHX2QWDP7SI5RROBVAUXKAU4ADKPAQC
7G5Y53RBBKF4QDPTVC2MFG45XHDOLEFPHA4XQIPJNW4RXCULMRQQC
VDX2MMS55XMEHH2TEMOOW225K6NGKB4QXPQFQ2WJLVXJK25BSXMQC
UAUV6SYV72FWMQVALN5YFTANLHIG6B5JHTZLJJUN5SN7SALYAC3AC
P7OMU7PBSC76C6FLDU3TT6ZRSKMNRTYAA4IM65ICVIHSMNUQWRBAC
2HKNCI4IG65FEWNSRBJ5SESMN4STJ6WSCNODP3UK6LBQMDHYPNTAC
GJA75BA6ZNFQL6DG7YSRQKJWGX52YJKL3DZO3OWO6D4HVH6JS7NQC
LD2TP6CDUHET2ISQB3P4JOTQTIDDPRLSZJTIYWAO7JTHKUWOF7MQC
const key = rnd.intRangeAtMostBiased(BENCH_KEY, std.math.minInt(BENCH_KEY), std.math.maxInt(BENCH_KEY));
try sl.insert(key, {});
const key = rnd.intRangeAtMostBiased(BENCH_KEY, std.math.minInt(BENCH_KEY), BENCH_ITEMS / 2);
const query_type = rnd.intRangeAtMostBiased(u8, 0, 99);
switch (query_type) {
0 => { // 1% remove
_ = try sl.remove(key);
},
1...9 => { // 9% insert
_ = try sl.insert(key, {});
},
else => { // 90% search
_ = sl.search(key);
},
}
// { // single thread
// var timer = try std.time.Timer.start();
var timer = try std.time.Timer.start();
var i: usize = 0;
while (i < BENCH_ITEMS) : (i += 1) {
// BENCH_ITEMS/20 means 50% of each call (remove, insert, search) hits a target
const key = rnd.intRangeAtMostBiased(BENCH_KEY, std.math.minInt(BENCH_KEY), BENCH_ITEMS / 20);
const query_type = rnd.intRangeAtMostBiased(u8, 0, 99);
switch (query_type) {
0 => { // 1% remove
st.total[0] = st.total[0] + 1;
if (sl.remove(key)) st.hit[0] = st.hit[0] + 1;
},
1...9 => { // 9% insert
st.total[1] = st.total[1] + 1;
if (try sl.insert(key, {})) st.hit[1] = st.hit[1] + 1;
},
else => { // 90% search
st.total[2] = st.total[2] + 1;
if (sl.search(key) != null) st.hit[2] = st.hit[2] + 1;
},
}
}
// var i: usize = 0;
// while (i < BENCH_ITEMS) : (i += 1) {
// const key = rnd.intRangeAtMostBiased(BENCH_KEY, std.math.minInt(BENCH_KEY), std.math.maxInt(BENCH_KEY));
// _ = try sl.insert(tsa.allocator(), key, {});
// }
std.debug.print("Lazy 1 thread: {d} ms\n", .{timer.read() / std.time.ns_per_ms});
std.debug.print("Total items: {d}, remove {d}/{d}, insert {d}/{d}, search {d}/{d}\n", .{
BENCH_ITEMS,
st.hit[0],
st.total[0],
st.hit[1],
st.total[1],
st.hit[2],
st.total[2],
});
}
fn benchLazyMT() !void {
const Functions = struct {
fn insert(skiplist: SL, key: BENCH_KEY, val: BENCH_VALUE) void {
_ = @call(std.builtin.CallModifier.auto, SL.insert, .{ skiplist, key, val }) catch unreachable;
}
fn remove(skiplist: SL, key: BENCH_KEY) void {
_ = @call(std.builtin.CallModifier.auto, SL.remove, .{ skiplist, key });
}
fn search(skiplist: SL, key: BENCH_KEY) void {
_ = @call(std.builtin.CallModifier.auto, SL.search, .{ skiplist, key });
}
};
var pool: std.Thread.Pool = undefined;
try pool.init(std.Thread.Pool.Options{
.allocator = std.heap.page_allocator,
.n_jobs = THREADS,
});
defer pool.deinit();
var wg = std.Thread.WaitGroup{};
var pool: std.Thread.Pool = undefined;
try pool.init(std.Thread.Pool.Options{
.allocator = std.heap.page_allocator,
});
defer pool.deinit();
var wg = std.Thread.WaitGroup{};
for (0..BENCH_ITEMS) |_| {
const key = rnd.intRangeAtMostBiased(
BENCH_KEY,
std.math.minInt(BENCH_KEY),
std.math.maxInt(BENCH_KEY),
);
pool.spawnWg(&wg, testIns, .{ &sl, key, {} });
const query_type = rnd.intRangeAtMostBiased(u8, 0, 99);
switch (query_type) {
0 => { // 1% remove
pool.spawnWg(&wg, Functions.remove, .{ sl, key });
},
1...9 => { // 9% insert
pool.spawnWg(&wg, Functions.insert, .{ sl, key, {} });
},
else => { // 90% search
pool.spawnWg(&wg, Functions.search, .{ sl, key });
},
fn testIns(skiplist: *SL, key: BENCH_KEY, val: BENCH_VALUE) void {
_ = @call(std.builtin.CallModifier.auto, SL.insert, .{ skiplist, key, val }) catch unreachable;
std.debug.print("Lazy {d} threads: {d} ms\n", .{
try std.Thread.getCpuCount(),
timer.read() / std.time.ns_per_ms,
});
try sq.add(std.heap.page_allocator, .{ .key = 1, .value = 1 });
try sq.add(std.heap.page_allocator, .{ .key = 2, .value = 2 });
try sq.add(std.heap.page_allocator, .{ .key = 3, .value = 3 });
try sq.add(std.heap.page_allocator, .{ .key = 0, .value = 4 });
try sq.add(.{ .key = 1, .value = 1 });
try sq.add(.{ .key = 2, .value = 2 });
try sq.add(.{ .key = 3, .value = 3 });
try sq.add(.{ .key = 0, .value = 4 });
std.debug.assert((try sq.remove(std.heap.page_allocator)).?.value == 4);
std.debug.assert((try sq.remove(std.heap.page_allocator)).?.value == 1);
std.debug.assert((try sq.remove(std.heap.page_allocator)).?.value == 2);
std.debug.assert((try sq.remove(std.heap.page_allocator)).?.value == 3);
std.debug.assert((try sq.remove(std.heap.page_allocator)) == null);
std.debug.assert((sq.remove()).?.value == 4);
std.debug.assert((sq.remove()).?.value == 1);
std.debug.assert((sq.remove()).?.value == 2);
std.debug.assert((sq.remove()).?.value == 3);
std.debug.assert((sq.remove()) == null);