Skip to content

Commit e4d2831

Browse files
authored
Merge pull request #9 from gotchacode/zig-port
Zig port
2 parents 1d093b6 + 9a479e2 commit e4d2831

File tree

7 files changed

+283
-93
lines changed

7 files changed

+283
-93
lines changed

.github/workflows/zig.yml

Lines changed: 46 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,55 @@ on:
77
branches: [ main, zig-port ]
88

99
jobs:
10-
c-build:
10+
c-build-gcc:
11+
name: C Build (GCC)
1112
runs-on: ubuntu-latest
1213

1314
steps:
1415
- uses: actions/checkout@v4
1516

16-
- name: Build C version
17-
run: cd c && make clean && make
17+
- name: Check GCC version
18+
run: gcc --version
1819

19-
- name: Test C executable runs
20-
run: cd c && echo -e "hi\npython\nexit" | timeout 5 ./chat || true
20+
- name: Build with GCC (C17 and C23)
21+
run: cd c && make clean && make gcc-builds
22+
23+
- name: Test GCC C17 executable
24+
run: cd c && echo -e "hi\npython\nexit" | timeout 5 ./chat-gcc-c17 || true
25+
26+
- name: Test GCC C23 executable
27+
run: cd c && echo -e "hi\npython\nexit" | timeout 5 ./chat-gcc-c23 || true
28+
29+
- name: Show binary sizes
30+
run: ls -lh c/chat-gcc-*
31+
32+
c-build-clang:
33+
name: C Build (Clang)
34+
runs-on: ubuntu-latest
35+
36+
steps:
37+
- uses: actions/checkout@v4
38+
39+
- name: Install Clang
40+
run: sudo apt-get update && sudo apt-get install -y clang
41+
42+
- name: Check Clang version
43+
run: clang --version
44+
45+
- name: Build with Clang (C17 and C23)
46+
run: cd c && make clean && make clang-builds
47+
48+
- name: Test Clang C17 executable
49+
run: cd c && echo -e "hi\npython\nexit" | timeout 5 ./chat-clang-c17 || true
50+
51+
- name: Test Clang C23 executable
52+
run: cd c && echo -e "hi\npython\nexit" | timeout 5 ./chat-clang-c23 || true
53+
54+
- name: Show binary sizes
55+
run: ls -lh c/chat-clang-*
2156

2257
zig-build-and-test:
58+
name: Zig Build & Test
2359
runs-on: ubuntu-latest
2460

2561
steps:
@@ -30,10 +66,13 @@ jobs:
3066
version: 0.15.2
3167

3268
- name: Build Zig chatbot
33-
run: cd zig && mkdir -p zig-out/bin && zig build-exe src/main.zig -femit-bin=zig-out/bin/chat
69+
run: cd zig && zig build
3470

3571
- name: Run Zig tests
36-
run: cd zig && zig test src/chatbot.zig
72+
run: cd zig && zig build test
3773

3874
- name: Test Zig executable runs
3975
run: cd zig && echo -e "hi\npython\nexit" | timeout 5 ./zig-out/bin/chat || true
76+
77+
- name: Show binary size
78+
run: ls -lh zig/zig-out/bin/chat

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,7 @@ chat
2727
# Zig build artifacts
2828
.zig-cache/
2929
zig-out/
30+
c/chat-clang-c17
31+
c/chat-clang-c23
32+
c/chat-gcc-c17
33+
c/chat-gcc-c23

BENCHMARK.md

Lines changed: 73 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,94 @@
1-
# Chatbot Build Benchmark Results
1+
# Chatbot Build & Runtime Benchmark Results
22

3-
Benchmark comparing C and Zig implementations of the chatbot.
3+
Benchmark comparing C (GCC and Clang, C17 and C23 standards) and Zig implementations.
44

55
**System:** macOS arm64
66
**Date:** 2026-01-12
77

8-
## Results
8+
## Compiler Versions (Local)
9+
10+
11+
| Compiler | Version |
12+
| ----------- | -------------------------------------------- |
13+
| GCC (macOS) | Apple Clang 17.0.0 (gcc is aliased to clang) |
14+
| Clang | Homebrew Clang 21.1.8 |
15+
| Zig | 0.15.2 |
16+
17+
18+
## Runtime Results
19+
20+
21+
| Version | Execution Time | Relative |
22+
| --------- | -------------- | --------------- |
23+
| GCC C17 | 228ms | 2.23x |
24+
| GCC C23 | 102ms | 1.00x (fastest) |
25+
| Clang C17 | 107ms | 1.04x |
26+
| Clang C23 | 106ms | 1.03x |
27+
| Zig | 628ms | 6.15x |
28+
29+
30+
## Binary Sizes
31+
32+
33+
| Version | Size |
34+
| --------- | ---- |
35+
| GCC C17 | 33K |
36+
| GCC C23 | 33K |
37+
| Clang C17 | 33K |
38+
| Clang C23 | 33K |
39+
| Zig | 1.3M |
940

10-
| Metric | C | Zig | Difference |
11-
|--------|---|-----|-----------|
12-
| Build Time | 93ms | 710ms | Zig is 7.63x slower |
13-
| Executable Size | 33K | 1.3M | Zig is 39x larger |
1441

1542
## Analysis
1643

17-
### Build Time
18-
- **C (93ms)**: Fast compilation using GCC with minimal optimization
19-
- **Zig (710ms)**: Longer compilation time due to Zig's more comprehensive compiler
44+
### C Compilers
45+
46+
- **GCC C23** was fastest in this run (times vary between runs)
47+
- **Clang** produces consistently fast binaries across C17/C23
48+
- On macOS, `gcc` is actually Apple Clang; real GCC is tested on CI (Ubuntu)
49+
50+
### Zig
51+
52+
- Slower due to:
53+
- GeneralPurposeAllocator overhead vs C's stack allocation
54+
- Zig 0.15 buffered I/O system overhead
55+
- Additional runtime safety checks
56+
- Much larger binary (embeds stdlib, no libc dependency)
57+
58+
### Binary Size
2059

21-
The C version compiles significantly faster due to:
22-
- Simpler compilation pipeline
23-
- No build system overhead (direct gcc command)
24-
- Minimal type checking and analysis
60+
- All C versions: 33K (links against system libc)
61+
- Zig: 1.3M (self-contained, no external dependencies)
2562

26-
### Executable Size
27-
- **C (33K)**: Small, minimal runtime
28-
- **Zig (1.3M)**: Larger due to Zig's standard library and runtime
63+
## Build Configuration
64+
65+
66+
| Compiler | Flags |
67+
| --------- | ---------------------------------------- |
68+
| GCC C17 | `gcc -std=c17 -Wall -Wextra -pedantic` |
69+
| GCC C23 | `gcc -std=c23 -Wall -Wextra -pedantic` |
70+
| Clang C17 | `clang -std=c17 -Wall -Wextra -pedantic` |
71+
| Clang C23 | `clang -std=c23 -Wall -Wextra -pedantic` |
72+
| Zig | `zig build` (debug mode) |
2973

30-
The Zig executable is larger because:
31-
- Zig stdlib is embedded in the binary
32-
- More comprehensive runtime features
33-
- GeneralPurposeAllocator adds overhead
3474

3575
## Notes
3676

37-
- Both versions are unoptimized builds
38-
- C build uses `-std=c11 -Wall -Wextra -pedantic`
39-
- Zig build uses default optimization level
40-
- Times are from cold builds (no cache)
77+
- All versions produce identical output
78+
- C23 falls back to `-std=c2x` on older compilers
79+
- Times vary between runs; relative performance is more meaningful
80+
- CI tests both GCC and Clang on Ubuntu
4181

42-
## Running the Benchmark
82+
## Running the Benchmarks
4383

4484
```bash
85+
# Full runtime benchmark (all compilers)
86+
./run_benchmarks.sh
87+
88+
# Build-only benchmark
4589
./benchmark.sh
90+
91+
# Show detected compilers
92+
cd c && make info
4693
```
4794

48-
This will clean, rebuild both versions, and compare build times and sizes.

c/Makefile

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,56 @@
1-
all:
2-
gcc -std=c11 -Wall -Wextra -pedantic src/chatbot.c -o chat
1+
# Detect real GCC vs Apple's gcc alias
2+
UNAME_S := $(shell uname -s)
3+
ifeq ($(UNAME_S),Darwin)
4+
# macOS: gcc is actually clang, use explicit paths if available
5+
GCC := $(shell which gcc-14 gcc-13 gcc-12 2>/dev/null | head -1)
6+
ifeq ($(GCC),)
7+
GCC := gcc
8+
GCC_NOTE := "(Apple Clang)"
9+
endif
10+
else
11+
GCC := gcc
12+
endif
13+
14+
CLANG := clang
15+
CFLAGS_COMMON = -Wall -Wextra -pedantic
16+
SRC = src/chatbot.c
17+
18+
# Default targets
19+
all: gcc-builds clang-builds
20+
21+
# GCC builds
22+
gcc-builds: chat-gcc-c17 chat-gcc-c23
23+
24+
chat-gcc-c17:
25+
$(GCC) -std=c17 $(CFLAGS_COMMON) $(SRC) -o chat-gcc-c17
26+
27+
chat-gcc-c23:
28+
$(GCC) -std=c23 $(CFLAGS_COMMON) $(SRC) -o chat-gcc-c23 2>/dev/null || \
29+
$(GCC) -std=c2x $(CFLAGS_COMMON) $(SRC) -o chat-gcc-c23
30+
31+
# Clang builds
32+
clang-builds: chat-clang-c17 chat-clang-c23
33+
34+
chat-clang-c17:
35+
$(CLANG) -std=c17 $(CFLAGS_COMMON) $(SRC) -o chat-clang-c17
36+
37+
chat-clang-c23:
38+
$(CLANG) -std=c23 $(CFLAGS_COMMON) $(SRC) -o chat-clang-c23 2>/dev/null || \
39+
$(CLANG) -std=c2x $(CFLAGS_COMMON) $(SRC) -o chat-clang-c23
40+
41+
# Legacy targets for backwards compatibility
42+
chat: chat-gcc-c17
43+
cp chat-gcc-c17 chat
44+
45+
chat-c17: chat-gcc-c17
46+
cp chat-gcc-c17 chat-c17
47+
48+
chat-c23: chat-gcc-c23
49+
cp chat-gcc-c23 chat-c23
350

451
clean:
5-
rm -rf *.o chat
52+
rm -rf *.o chat chat-c17 chat-c23 chat-gcc-* chat-clang-*
53+
54+
info:
55+
@echo "GCC: $(GCC) $(GCC_NOTE)"
56+
@echo "Clang: $(CLANG)"

c/src/chatbot.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1+
// Enable POSIX/GNU extensions (strdup, strncasecmp, etc.)
2+
// _GNU_SOURCE is needed because -std=c17 disables extensions by default
3+
#define _GNU_SOURCE
4+
15
#include <stdlib.h>
26
#include <stdio.h>
7+
#include <string.h>
38
#include <ctype.h>
49
#include <limits.h>
5-
#include <strings.h>
610
#include "chatbot.h"
711

812
// hash table implementation from here

0 commit comments

Comments
 (0)