Skip to content

Commit f293fe6

Browse files
committed
Add runtime benchmark script with proper stdin handling for both versions
1 parent f50809e commit f293fe6

File tree

3 files changed

+133
-12
lines changed

3 files changed

+133
-12
lines changed

run_benchmarks.sh

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
#!/bin/bash
2+
3+
set -e
4+
5+
echo "=========================================="
6+
echo "Chatbot Runtime Benchmark & Testing"
7+
echo "=========================================="
8+
echo ""
9+
10+
# Build both versions
11+
echo "Building both versions..."
12+
echo ""
13+
14+
cd c
15+
make clean > /dev/null 2>&1
16+
make > /dev/null 2>&1
17+
cd ..
18+
19+
cd zig
20+
rm -rf zig-out .zig-cache > /dev/null 2>&1
21+
mkdir -p zig-out/bin
22+
zig build-exe src/main.zig -femit-bin=zig-out/bin/chat > /dev/null 2>&1
23+
cd ..
24+
25+
echo "Build complete!"
26+
echo ""
27+
28+
# Test C version
29+
echo "=========================================="
30+
echo "C Version Testing & Benchmarking"
31+
echo "=========================================="
32+
echo ""
33+
echo "Running with test inputs..."
34+
35+
C_START=$(date +%s%N)
36+
c/./chat < test_inputs.txt > /tmp/c_output.txt 2>&1
37+
C_END=$(date +%s%N)
38+
C_TIME=$(( (C_END - C_START) / 1000000 )) # milliseconds
39+
40+
echo "Output:"
41+
cat /tmp/c_output.txt
42+
echo ""
43+
echo "Execution time: ${C_TIME}ms"
44+
echo ""
45+
46+
# Test Zig version
47+
echo "=========================================="
48+
echo "Zig Version Testing & Benchmarking"
49+
echo "=========================================="
50+
echo ""
51+
echo "Running with test inputs..."
52+
53+
ZIG_START=$(date +%s%N)
54+
zig/zig-out/bin/./chat < test_inputs.txt > /tmp/zig_output.txt 2>&1
55+
ZIG_END=$(date +%s%N)
56+
ZIG_TIME=$(( (ZIG_END - ZIG_START) / 1000000 )) # milliseconds
57+
58+
echo "Output:"
59+
cat /tmp/zig_output.txt
60+
echo ""
61+
echo "Execution time: ${ZIG_TIME}ms"
62+
echo ""
63+
64+
# Compare outputs
65+
echo "=========================================="
66+
echo "Output Comparison"
67+
echo "=========================================="
68+
echo ""
69+
70+
if diff -q /tmp/c_output.txt /tmp/zig_output.txt > /dev/null 2>&1; then
71+
echo "✓ Outputs are identical"
72+
else
73+
echo "✗ Outputs differ"
74+
echo ""
75+
echo "C output:"
76+
cat /tmp/c_output.txt
77+
echo ""
78+
echo "Zig output:"
79+
cat /tmp/zig_output.txt
80+
fi
81+
82+
echo ""
83+
84+
# Runtime comparison
85+
echo "=========================================="
86+
echo "Runtime Comparison"
87+
echo "=========================================="
88+
echo ""
89+
90+
if [ $C_TIME -lt $ZIG_TIME ]; then
91+
RATIO=$(echo "scale=2; $ZIG_TIME / $C_TIME" | bc)
92+
echo "C version is ${RATIO}x faster"
93+
else
94+
RATIO=$(echo "scale=2; $C_TIME / $ZIG_TIME" | bc)
95+
echo "Zig version is ${RATIO}x faster"
96+
fi
97+
98+
echo ""
99+
echo "Summary:"
100+
echo " C: ${C_TIME}ms"
101+
echo " Zig: ${ZIG_TIME}ms"
102+
echo ""

test_inputs.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
hi
2+
hey
3+
python
4+
light
5+
what
6+
unknown_keyword
7+
hear
8+
hello
9+
python
10+
light
11+
exit

zig/src/main.zig

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
const std = @import("std");
22
const chatbot = @import("chatbot.zig");
3+
const c = @cImport({
4+
@cInclude("stdio.h");
5+
@cInclude("string.h");
6+
@cInclude("ctype.h");
7+
});
38

49
pub fn main() !void {
510
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
611
defer _ = gpa.deinit();
712
const allocator = gpa.allocator();
813

9-
std.debug.print("$ Chatbot v1.0.0!\n", .{});
14+
_ = c.printf("$ Chatbot v1.0.0!\n", );
1015

1116
// Create hash table
1217
var ht = try chatbot.HashTable.create(allocator, 65536);
@@ -18,21 +23,25 @@ pub fn main() !void {
1823
try ht.set("hear", "What you heard is right");
1924
try ht.set("python", "Yo, I love Python");
2025
try ht.set("light", "I like light");
21-
try ht.set("what", "It is clear, ain't it?");
26+
try ht.set("What", "It is clear, ain't it?");
2227

23-
// Hardcoded test inputs
24-
const inputs = [_][]const u8{ "hi", "python", "what", "exit" };
28+
var buf: [chatbot.LineLength]u8 = undefined;
2529

26-
for (inputs) |input| {
27-
std.debug.print("\n$ (user) {s}\n", .{input});
30+
while (true) {
31+
_ = c.printf("\n$ (user) ", );
2832

29-
const trimmed = std.mem.trim(u8, input, " \t\r\n");
30-
if (trimmed.len == 0) continue;
33+
const result = c.fgets(&buf, chatbot.LineLength, c.stdin());
34+
if (result == null) break;
35+
36+
if (@as(usize, c.strlen(&buf)) <= 1) break;
37+
38+
const line = buf[0..c.strlen(&buf)];
39+
const trimmed = std.mem.trim(u8, line, " \t\r\n");
40+
if (trimmed.len == 0) break;
3141

3242
var word_iter = std.mem.tokenizeAny(u8, trimmed, chatbot.SeparatorChars);
3343

3444
while (word_iter.next()) |word| {
35-
// Convert to lowercase for comparison
3645
const lower_word = try allocator.alloc(u8, word.len);
3746
defer allocator.free(lower_word);
3847

@@ -41,14 +50,13 @@ pub fn main() !void {
4150
}
4251

4352
if (std.mem.eql(u8, lower_word, "exit")) {
44-
std.debug.print("\n$ (chatbot) Goodbye!\n", .{});
4553
return;
4654
}
4755

4856
if (ht.get(lower_word)) |response| {
49-
std.debug.print("\n$ (chatbot) {s}\n", .{response});
57+
_ = c.printf("\n$ (chatbot) %s\n", response.ptr);
5058
} else {
51-
std.debug.print("\n$ (chatbot) {s}\n", .{"Sorry, I don't know what to say about that"});
59+
_ = c.printf("\n$ (chatbot) %s\n", "Sorry, I don't know what to say about that");
5260
}
5361
}
5462
}

0 commit comments

Comments
 (0)