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 @@ -30,6 +30,7 @@ HEMLOCKC_BIN="../hemlock/hemlockc" ./run.sh
- **primes_sieve** - Sieve of Eratosthenes (array access, loops)
- **json_serialize** - JSON serialization (object creation, string building)
- **json_deserialize** - JSON parsing (string parsing, object creation)
- **regex_match** - Regular expression matching on large text (pattern matching, string scanning)

## Notes

Expand Down
5 changes: 5 additions & 0 deletions benchmarks.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@
"description": "Sieve of Eratosthenes",
"default_input": 1000000,
"quick_input": 100000
},
"regex_match": {
"description": "Regular expression matching",
"default_input": 10000,
"quick_input": 1000
}
},
"languages": {
Expand Down
81 changes: 81 additions & 0 deletions benchmarks/regex_match/regex_match.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <regex.h>

// Generate test text with patterns to match
char* generate_text(int iterations) {
const char* base = "The quick brown fox jumps over the lazy dog. "
"Email: user123@example.com Phone: 555-1234 "
"Date: 2024-01-15 Price: $99.99 "
"URL: https://www.example.com/path?query=value "
"IP: 192.168.1.1 Code: ABC-123-XYZ\n";
size_t base_len = strlen(base);
size_t total_len = base_len * iterations;

char* text = malloc(total_len + 1);
if (!text) return NULL;

char* ptr = text;
for (int i = 0; i < iterations; i++) {
memcpy(ptr, base, base_len);
ptr += base_len;
}
*ptr = '\0';

return text;
}

// Count all matches of a pattern in text
int count_matches(const char* text, const char* pattern) {
regex_t regex;
regmatch_t match;
int count = 0;

if (regcomp(&regex, pattern, REG_EXTENDED) != 0) {
return 0;
}

const char* ptr = text;
while (regexec(&regex, ptr, 1, &match, 0) == 0) {
count++;
ptr += match.rm_eo;
if (*ptr == '\0') break;
}

regfree(&regex);
return count;
}

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

char* text = generate_text(iterations);
if (!text) {
fprintf(stderr, "Failed to allocate memory\n");
return 1;
}

// Various regex patterns to test different matching scenarios
const char* patterns[] = {
"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}", // Email
"[0-9]{3}-[0-9]{4}", // Phone
"[0-9]{4}-[0-9]{2}-[0-9]{2}", // Date
"\\$[0-9]+\\.[0-9]{2}", // Price
"https?://[a-zA-Z0-9.-]+/[a-zA-Z0-9/?=&._-]*", // URL
"[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}", // IP
"[A-Z]{3}-[0-9]{3}-[A-Z]{3}", // Code
"\\b[a-z]{4,}\\b" // 4+ letter words
};
int num_patterns = sizeof(patterns) / sizeof(patterns[0]);

int total_matches = 0;
for (int i = 0; i < num_patterns; i++) {
total_matches += count_matches(text, patterns[i]);
}

printf("%d\n", total_matches);

free(text);
return 0;
}
Loading