Skip to content
Merged
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
39 changes: 39 additions & 0 deletions .github/workflows/zig.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: Build & Tests

on:
push:
branches: [ main, zig-port ]
pull_request:
branches: [ main, zig-port ]

jobs:
c-build:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Build C version
run: cd c && make clean && make

- name: Test C executable runs
run: cd c && echo -e "hi\npython\nexit" | timeout 5 ./chat || true

zig-build-and-test:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- uses: goto-bus-stop/setup-zig@v2
with:
version: 0.15.2

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

- name: Run Zig tests
run: cd zig && zig test src/chatbot.zig

- name: Test Zig executable runs
run: cd zig && echo -e "hi\npython\nexit" | timeout 5 ./zig-out/bin/chat || true
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,7 @@ chat
*.i*86
*.x86_64
*.hex

# Zig build artifacts
.zig-cache/
zig-out/
48 changes: 48 additions & 0 deletions BENCHMARK.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Chatbot Build Benchmark Results

Benchmark comparing C and Zig implementations of the chatbot.

**System:** macOS arm64
**Date:** 2026-01-12

## Results

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

## Analysis

### Build Time
- **C (93ms)**: Fast compilation using GCC with minimal optimization
- **Zig (710ms)**: Longer compilation time due to Zig's more comprehensive compiler

The C version compiles significantly faster due to:
- Simpler compilation pipeline
- No build system overhead (direct gcc command)
- Minimal type checking and analysis

### Executable Size
- **C (33K)**: Small, minimal runtime
- **Zig (1.3M)**: Larger due to Zig's standard library and runtime

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

## Notes

- Both versions are unoptimized builds
- C build uses `-std=c11 -Wall -Wextra -pedantic`
- Zig build uses default optimization level
- Times are from cold builds (no cache)

## Running the Benchmark

```bash
./benchmark.sh
```

This will clean, rebuild both versions, and compare build times and sizes.
69 changes: 69 additions & 0 deletions benchmark.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#!/bin/bash

set -e

echo "=========================================="
echo "Chatbot Build Benchmark"
echo "=========================================="
echo ""

# C Version Benchmark
echo "C Version Benchmark"
echo "------------------------------------------"

cd c
echo "Cleaning..."
make clean > /dev/null 2>&1

echo "Building C version..."
C_START=$(date +%s%N)
make > /dev/null 2>&1
C_END=$(date +%s%N)
C_TIME=$(( (C_END - C_START) / 1000000 )) # Convert to milliseconds

C_SIZE=$(ls -lh chat | awk '{print $5}')

echo "Build time: ${C_TIME}ms"
echo "Executable size: ${C_SIZE}"

cd ..
echo ""

# Zig Version Benchmark
echo "Zig Version Benchmark"
echo "------------------------------------------"

cd zig
echo "Cleaning..."
rm -rf zig-out .zig-cache > /dev/null 2>&1
mkdir -p zig-out/bin

echo "Building Zig version..."
ZIG_START=$(date +%s%N)
zig build-exe src/main.zig -femit-bin=zig-out/bin/chat > /dev/null 2>&1
ZIG_END=$(date +%s%N)
ZIG_TIME=$(( (ZIG_END - ZIG_START) / 1000000 )) # Convert to milliseconds

ZIG_SIZE=$(ls -lh zig-out/bin/chat | awk '{print $5}')

echo "Build time: ${ZIG_TIME}ms"
echo "Executable size: ${ZIG_SIZE}"

cd ..
echo ""

# Comparison
echo "Comparison"
echo "------------------------------------------"
if [ $C_TIME -lt $ZIG_TIME ]; then
RATIO=$(echo "scale=2; $ZIG_TIME / $C_TIME" | bc)
echo "C version is ${RATIO}x faster"
else
RATIO=$(echo "scale=2; $C_TIME / $ZIG_TIME" | bc)
echo "Zig version is ${RATIO}x faster"
fi

echo ""
echo "Summary:"
echo " C: ${C_TIME}ms, ${C_SIZE}"
echo " Zig: ${ZIG_TIME}ms, ${ZIG_SIZE}"
2 changes: 1 addition & 1 deletion Makefile → c/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ all:
gcc -std=c11 -Wall -Wextra -pedantic src/chatbot.c -o chat

clean:
rm -rf *o chat
rm -rf *.o chat
File renamed without changes.
File renamed without changes.
Empty file removed example.c
Empty file.
79 changes: 57 additions & 22 deletions readme.md
Original file line number Diff line number Diff line change
@@ -1,46 +1,81 @@
# Chatbot

[![Build Status](https://travis-ci.org/vinitkumar/chatbot.svg?branch=master)](https://travis-ci.org/vinitkumar/chatbot)
A simple keyword-based chatbot with implementations in both C and Zig.

Chatbot is a simple bot written in C. The base algorithm is that our conversation is based on keywords. The bot seaches for this keyword and present a suitable response on basis of that keyword.
## Benchmarks

## Installation
### Build Time & Size

Installation is very easy via `MakeFile` :
See [BENCHMARK.md](BENCHMARK.md) for detailed build metrics.

Just run:
| Metric | C | Zig | Difference |
|--------|---|-----|-----------|
| Build Time | 93ms | 710ms | Zig is 7.63x slower |
| Executable Size | 33K | 1.3M | Zig is 39x larger |

Run build benchmark:
```bash
./benchmark.sh
```
chatbot ➤ make
gcc src/chatbot.c -o chat

### Runtime Performance

Both versions produce identical output. Runtime measurements with test inputs:

| Metric | C | Zig | Difference |
|--------|---|-----|-----------|
| Execution Time | 286ms | 526ms | C is 1.83x faster |

Run runtime benchmark:
```bash
./run_benchmarks.sh
```

## Usage
## Building

### C Version

After running `make all` you get a executable named as `chat`. Now run `./chat` and start chatting with the bot.
```bash
cd c
make
./chat
```

See `c/Makefile` for more details.

## Demo
### Zig Version

```bash
cd zig
zig build-exe src/main.zig -femit-bin=zig-out/bin/chat
./zig-out/bin/chat
```
chatbot ➤ ./chat
$ Chatbot v1.0.0!

$ (user) hi
Or use the Zig build system:

$ (chatbot) hello
```bash
cd zig
zig build run
```

$ (user) python
See `zig/README.md` for more details.

$ (chatbot) Yo, I love Python
## Testing

$ (user) What
### C Version

$ (chatbot) It is clear, ain't it?
No automated tests (original implementation).

$ (user) exit
### Zig Version

```bash
cd zig
zig test src/chatbot.zig
```

## Issues and Pull request.
Or:

Feel free to create an issue if you notice a bug. Pull request are really
welcome with good fixes.
```bash
cd zig
zig build test
```
102 changes: 102 additions & 0 deletions run_benchmarks.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#!/bin/bash

set -e

echo "=========================================="
echo "Chatbot Runtime Benchmark & Testing"
echo "=========================================="
echo ""

# Build both versions
echo "Building both versions..."
echo ""

cd c
make clean > /dev/null 2>&1
make > /dev/null 2>&1
cd ..

cd zig
rm -rf zig-out .zig-cache > /dev/null 2>&1
mkdir -p zig-out/bin
zig build-exe src/main.zig -femit-bin=zig-out/bin/chat > /dev/null 2>&1
cd ..

echo "Build complete!"
echo ""

# Test C version
echo "=========================================="
echo "C Version Testing & Benchmarking"
echo "=========================================="
echo ""
echo "Running with test inputs..."

C_START=$(date +%s%N)
c/./chat < test_inputs.txt > /tmp/c_output.txt 2>&1
C_END=$(date +%s%N)
C_TIME=$(( (C_END - C_START) / 1000000 )) # milliseconds

echo "Output:"
cat /tmp/c_output.txt
echo ""
echo "Execution time: ${C_TIME}ms"
echo ""

# Test Zig version
echo "=========================================="
echo "Zig Version Testing & Benchmarking"
echo "=========================================="
echo ""
echo "Running with test inputs..."

ZIG_START=$(date +%s%N)
zig/zig-out/bin/./chat < test_inputs.txt > /tmp/zig_output.txt 2>&1
ZIG_END=$(date +%s%N)
ZIG_TIME=$(( (ZIG_END - ZIG_START) / 1000000 )) # milliseconds

echo "Output:"
cat /tmp/zig_output.txt
echo ""
echo "Execution time: ${ZIG_TIME}ms"
echo ""

# Compare outputs
echo "=========================================="
echo "Output Comparison"
echo "=========================================="
echo ""

if diff -q /tmp/c_output.txt /tmp/zig_output.txt > /dev/null 2>&1; then
echo "✓ Outputs are identical"
else
echo "✗ Outputs differ"
echo ""
echo "C output:"
cat /tmp/c_output.txt
echo ""
echo "Zig output:"
cat /tmp/zig_output.txt
fi

echo ""

# Runtime comparison
echo "=========================================="
echo "Runtime Comparison"
echo "=========================================="
echo ""

if [ $C_TIME -lt $ZIG_TIME ]; then
RATIO=$(echo "scale=2; $ZIG_TIME / $C_TIME" | bc)
echo "C version is ${RATIO}x faster"
else
RATIO=$(echo "scale=2; $C_TIME / $ZIG_TIME" | bc)
echo "Zig version is ${RATIO}x faster"
fi

echo ""
echo "Summary:"
echo " C: ${C_TIME}ms"
echo " Zig: ${ZIG_TIME}ms"
echo ""
Empty file removed test.c
Empty file.
11 changes: 11 additions & 0 deletions test_inputs.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
hi
hey
python
light
what
unknown_keyword
hear
hello
python
light
exit
Loading
Loading