Skip to content
Open
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
1 change: 1 addition & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ HEMLOCKC_BIN="../hemlock/hemlockc" ./run.sh
- **graph_bfs** - Breadth-first search on graph (queue operations, adjacency list traversal)
- **json_serialize** - JSON serialization (object creation, string building)
- **json_deserialize** - JSON parsing (string parsing, object creation)
- **word_count** - Count words/lines in large text (classic MapReduce task)

## Notes

Expand Down
15 changes: 15 additions & 0 deletions benchmarks.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,21 @@
"description": "Sieve of Eratosthenes",
"default_input": 1000000,
"quick_input": 100000
},
"json_serialize": {
"description": "JSON serialization",
"default_input": 100000,
"quick_input": 10000
},
"json_deserialize": {
"description": "JSON parsing",
"default_input": 100000,
"quick_input": 10000
},
"word_count": {
"description": "Count words/lines in large text",
"default_input": 100000,
"quick_input": 10000
}
},
"languages": {
Expand Down
53 changes: 53 additions & 0 deletions benchmarks/word_count/word_count.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Word count benchmark - C
// Count words and lines in large generated text (classic MapReduce task)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

int main(int argc, char *argv[]) {
int n = argc > 1 ? atoi(argv[1]) : 100000;

const char *phrase = "the quick brown fox jumps over the lazy dog\n";
size_t phrase_len = strlen(phrase);

// Generate text: repeat phrase n times
size_t total_len = phrase_len * n;
char *text = malloc(total_len + 1);
if (!text) {
fprintf(stderr, "Memory allocation failed\n");
return 1;
}

char *ptr = text;
for (int i = 0; i < n; i++) {
memcpy(ptr, phrase, phrase_len);
ptr += phrase_len;
}
*ptr = '\0';

// Count words and lines
long words = 0;
long lines = 0;
int in_word = 0;

for (size_t i = 0; i < total_len; i++) {
char c = text[i];
if (c == '\n') {
lines++;
}
if (isspace((unsigned char)c)) {
in_word = 0;
} else {
if (!in_word) {
words++;
in_word = 1;
}
}
}

printf("%ld %ld\n", words, lines);
free(text);
return 0;
}
64 changes: 64 additions & 0 deletions benchmarks/word_count/word_count.hml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// Word count benchmark - Hemlock
// Count words and lines in large generated text (classic MapReduce task)

fn parse_int(s) {
let val = 0;
let idx = 0;
while (idx < s.length) {
let ch = s[idx];
let code: i32 = ch;
let zero: i32 = '0';
val = val * 10 + (code - zero);
idx = idx + 1;
}
return val;
}

fn is_whitespace(ch) {
let code: i32 = ch;
// space=32, tab=9, newline=10, carriage return=13
return code == 32 || code == 9 || code == 10 || code == 13;
}

let n = 100000;
if (args.length > 1) {
n = parse_int(args[1]);
}

let phrase = "the quick brown fox jumps over the lazy dog\n";

// Generate text: repeat phrase n times
let text = "";
let i = 0;
while (i < n) {
text = text + phrase;
i = i + 1;
}

// Count words and lines
let words = 0;
let lines = 0;
let in_word = false;
let newline: i32 = '\n';

let j = 0;
while (j < text.length) {
let ch = text[j];
let code: i32 = ch;

if (code == newline) {
lines = lines + 1;
}

if (is_whitespace(ch)) {
in_word = false;
} else {
if (!in_word) {
words = words + 1;
in_word = true;
}
}
j = j + 1;
}

print(words + " " + lines);
15 changes: 15 additions & 0 deletions benchmarks/word_count/word_count.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Word count benchmark - JavaScript
// Count words and lines in large generated text (classic MapReduce task)

const n = parseInt(process.argv[2]) || 100000;

const phrase = "the quick brown fox jumps over the lazy dog\n";

// Generate text: repeat phrase n times
const text = phrase.repeat(n);

// Count words and lines
const words = text.split(/\s+/).filter(w => w.length > 0).length;
const lines = (text.match(/\n/g) || []).length;

console.log(`${words} ${lines}`);
17 changes: 17 additions & 0 deletions benchmarks/word_count/word_count.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Word count benchmark - Python
# Count words and lines in large generated text (classic MapReduce task)

import sys

n = int(sys.argv[1]) if len(sys.argv) > 1 else 100000

phrase = "the quick brown fox jumps over the lazy dog\n"

# Generate text: repeat phrase n times
text = phrase * n

# Count words and lines
words = len(text.split())
lines = text.count('\n')

print(f"{words} {lines}")
15 changes: 15 additions & 0 deletions benchmarks/word_count/word_count.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Word count benchmark - Ruby
# Count words and lines in large generated text (classic MapReduce task)

n = ARGV[0] ? ARGV[0].to_i : 100000

phrase = "the quick brown fox jumps over the lazy dog\n"

# Generate text: repeat phrase n times
text = phrase * n

# Count words and lines
words = text.split.length
lines = text.count("\n")

puts "#{words} #{lines}"
7 changes: 5 additions & 2 deletions run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ usage() {
echo " --iter N Number of iterations (default: 3)"
echo " --help, -h Show this help"
echo ""
echo "Benchmarks: fib, array_sum, string_concat, primes_sieve, quicksort, binary_tree, graph_bfs, json_serialize, json_deserialize"
echo "Benchmarks: fib, array_sum, string_concat, primes_sieve, quicksort, binary_tree, graph_bfs, json_serialize, json_deserialize, word_count"
echo " (leave empty to run all)"
}

Expand Down Expand Up @@ -87,6 +87,9 @@ get_input() {
json_deserialize)
[[ $QUICK_MODE -eq 1 ]] && echo 10000 || echo 100000
;;
word_count)
[[ $QUICK_MODE -eq 1 ]] && echo 10000 || echo 100000
;;
esac
}

Expand Down Expand Up @@ -210,7 +213,7 @@ run_all() {
if [[ -n "$BENCHMARK" ]]; then
benchmarks="$BENCHMARK"
else
benchmarks="fib array_sum string_concat primes_sieve quicksort binary_tree graph_bfs json_serialize json_deserialize"
benchmarks="fib array_sum string_concat primes_sieve quicksort binary_tree graph_bfs json_serialize json_deserialize word_count"
fi

local languages="c hemlockc hemlock python javascript ruby"
Expand Down