feat: add benchmarking stdlib with memory safety checks and example scripts
Implement a new `benchmark` standard library module providing high-precision nanosecond timing functions (`bench_start`, `bench_end`, `bench_format`, `bench_format_auto`, `bench_reset`). Add a dedicated `memory.c` module with runtime memory safety validation, including stack overflow detection, local variable limit enforcement, and high-water mark tracking. Integrate memory checks into the interpreter's variable declaration path in `src/interpreter.c` and initialize the memory subsystem in `src/main.c`. Update the build system (`Makefile`) to compile the new source files and include benchmark tests in the test suite. Extend `TUTORIAL.md` with comprehensive documentation for the benchmarking API and random number functions (`rand`, `srand`, `rand_range`, `time`). Add two example scripts (`examples/bench.rc` and `examples/benchmark_demo.rc`) demonstrating performance measurement of recursive Fibonacci, loop iterations, list operations, string concatenation, object creation, and sorting algorithms.
This commit is contained in:
@@ -0,0 +1,233 @@
|
||||
int modulo(int a, int b) {
|
||||
return a - (a / b) * b;
|
||||
}
|
||||
|
||||
int fibonacci_recursive(int n) {
|
||||
if (n <= 1) { return n; }
|
||||
return fibonacci_recursive(n - 1) + fibonacci_recursive(n - 2);
|
||||
}
|
||||
|
||||
int loop_iteration(int iterations) {
|
||||
int total = 0;
|
||||
int i = 0;
|
||||
while (i < iterations) {
|
||||
total = total + i * 2;
|
||||
i = i + 1;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
int list_operations(int iterations) {
|
||||
int sum = 0;
|
||||
int i = 0;
|
||||
int val = 0;
|
||||
while (i < iterations) {
|
||||
if (modulo(i, 3) == 0) {
|
||||
val = i * 2;
|
||||
sum = sum + val;
|
||||
}
|
||||
i = i + 1;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
int string_concatenation(int iterations) {
|
||||
char *result = "";
|
||||
int i = 0;
|
||||
while (i < iterations) {
|
||||
result = result + "x";
|
||||
i = i + 1;
|
||||
}
|
||||
return strlen(result);
|
||||
}
|
||||
|
||||
class BenchItem {
|
||||
int id = 0;
|
||||
int value = 0;
|
||||
int active = 0;
|
||||
}
|
||||
|
||||
int dict_creation(int iterations) {
|
||||
int sum = 0;
|
||||
int i = 0;
|
||||
int obj = 0;
|
||||
while (i < iterations) {
|
||||
obj = new BenchItem();
|
||||
obj.id = i;
|
||||
obj.value = i * 2;
|
||||
obj.active = modulo(i, 2);
|
||||
sum = sum + obj.value;
|
||||
i = i + 1;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
int sorting_algorithm(int iterations) {
|
||||
int arr[1000];
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
int limit = 0;
|
||||
int left = 0;
|
||||
int right = 0;
|
||||
if (iterations > 1000) { iterations = 1000; }
|
||||
while (i < iterations) {
|
||||
arr[i] = rand_range(0, 1000);
|
||||
i = i + 1;
|
||||
}
|
||||
i = 0;
|
||||
while (i < iterations - 1) {
|
||||
j = 0;
|
||||
limit = iterations - i - 1;
|
||||
while (j < limit) {
|
||||
left = arr[j];
|
||||
right = arr[j + 1];
|
||||
if (left > right) {
|
||||
arr[j] = right;
|
||||
arr[j + 1] = left;
|
||||
}
|
||||
j = j + 1;
|
||||
}
|
||||
i = i + 1;
|
||||
}
|
||||
return arr[0];
|
||||
}
|
||||
|
||||
int math_operations(int iterations) {
|
||||
int total = 0;
|
||||
int i = 0;
|
||||
int sq = 0;
|
||||
int s = 0;
|
||||
int c = 0;
|
||||
while (i < iterations) {
|
||||
sq = sqrt(i);
|
||||
s = sin(i);
|
||||
c = cos(i);
|
||||
total = total + sq * s / 1000000 * c / 1000000;
|
||||
i = i + 1;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
int main() {
|
||||
srand(time());
|
||||
int iterations = 1000;
|
||||
int fib_n = 20;
|
||||
int timer = 0;
|
||||
int t = 0;
|
||||
int r = 0;
|
||||
int total_time = 0;
|
||||
|
||||
int durations[7];
|
||||
char *names[7];
|
||||
int min_idx = 0;
|
||||
int max_idx = 0;
|
||||
int min_val = 0;
|
||||
int max_val = 0;
|
||||
int i = 0;
|
||||
int d = 0;
|
||||
|
||||
names[0] = "Fibonacci Recursive";
|
||||
names[1] = "Loop Iteration";
|
||||
names[2] = "List Operations";
|
||||
names[3] = "String Concatenation";
|
||||
names[4] = "Dict Creation";
|
||||
names[5] = "Sorting Algorithm";
|
||||
names[6] = "Math Operations";
|
||||
|
||||
printf("\n======================================================================\n");
|
||||
printf("RC PERFORMANCE BENCHMARK\n");
|
||||
printf("======================================================================\n");
|
||||
printf("Iterations: %d | Fibonacci N: %d\n", iterations, fib_n);
|
||||
printf("======================================================================\n\n");
|
||||
|
||||
printf("Running: Fibonacci Recursive... ");
|
||||
timer = bench_start();
|
||||
r = fibonacci_recursive(fib_n);
|
||||
t = bench_end(timer);
|
||||
durations[0] = t;
|
||||
total_time = total_time + t;
|
||||
printf("%s\n", bench_format(t, 2));
|
||||
printf(" Result: %d\n\n", r);
|
||||
|
||||
printf("Running: Loop Iteration... ");
|
||||
timer = bench_start();
|
||||
r = loop_iteration(iterations);
|
||||
t = bench_end(timer);
|
||||
durations[1] = t;
|
||||
total_time = total_time + t;
|
||||
printf("%s\n", bench_format(t, 2));
|
||||
printf(" Result: %d\n\n", r);
|
||||
|
||||
printf("Running: List Operations... ");
|
||||
timer = bench_start();
|
||||
r = list_operations(iterations);
|
||||
t = bench_end(timer);
|
||||
durations[2] = t;
|
||||
total_time = total_time + t;
|
||||
printf("%s\n", bench_format(t, 2));
|
||||
printf(" Result: %d\n\n", r);
|
||||
|
||||
printf("Running: String Concatenation... ");
|
||||
timer = bench_start();
|
||||
r = string_concatenation(iterations);
|
||||
t = bench_end(timer);
|
||||
durations[3] = t;
|
||||
total_time = total_time + t;
|
||||
printf("%s\n", bench_format(t, 2));
|
||||
printf(" Result: %d\n\n", r);
|
||||
|
||||
printf("Running: Dict Creation... ");
|
||||
timer = bench_start();
|
||||
r = dict_creation(iterations);
|
||||
t = bench_end(timer);
|
||||
durations[4] = t;
|
||||
total_time = total_time + t;
|
||||
printf("%s\n", bench_format(t, 2));
|
||||
printf(" Result: %d\n\n", r);
|
||||
|
||||
printf("Running: Sorting Algorithm... ");
|
||||
timer = bench_start();
|
||||
r = sorting_algorithm(iterations);
|
||||
t = bench_end(timer);
|
||||
durations[5] = t;
|
||||
total_time = total_time + t;
|
||||
printf("%s\n", bench_format(t, 2));
|
||||
printf(" Result: %d\n\n", r);
|
||||
|
||||
printf("Running: Math Operations... ");
|
||||
timer = bench_start();
|
||||
r = math_operations(iterations);
|
||||
t = bench_end(timer);
|
||||
durations[6] = t;
|
||||
total_time = total_time + t;
|
||||
printf("%s\n", bench_format(t, 2));
|
||||
printf(" Result: %d\n\n", r);
|
||||
|
||||
min_idx = 0;
|
||||
max_idx = 0;
|
||||
min_val = durations[0];
|
||||
max_val = durations[0];
|
||||
i = 1;
|
||||
while (i < 7) {
|
||||
d = durations[i];
|
||||
if (d < min_val) {
|
||||
min_val = d;
|
||||
min_idx = i;
|
||||
}
|
||||
if (d > max_val) {
|
||||
max_val = d;
|
||||
max_idx = i;
|
||||
}
|
||||
i = i + 1;
|
||||
}
|
||||
|
||||
printf("======================================================================\n");
|
||||
printf("SUMMARY\n");
|
||||
printf("======================================================================\n");
|
||||
printf("Total Time: %s\n", bench_format(total_time, 2));
|
||||
printf("Fastest Test: %s (%s)\n", names[min_idx], bench_format(durations[min_idx], 2));
|
||||
printf("Slowest Test: %s (%s)\n", names[max_idx], bench_format(durations[max_idx], 2));
|
||||
printf("======================================================================\n\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
int fibonacci(int n) {
|
||||
if (n <= 1) {
|
||||
return n;
|
||||
}
|
||||
return fibonacci(n - 1) + fibonacci(n - 2);
|
||||
}
|
||||
|
||||
int compute_sum_of_squares(int limit) {
|
||||
int sum = 0;
|
||||
int i = 1;
|
||||
while (i <= limit) {
|
||||
sum = sum + (i * i);
|
||||
i = i + 1;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
int main() {
|
||||
printf("=================================================\n");
|
||||
printf(" RC Language - Benchmarking Demo\n");
|
||||
printf("=================================================\n\n");
|
||||
|
||||
printf("This demo shows how to use the benchmarking stdlib\n");
|
||||
printf("to measure execution time of different operations.\n\n");
|
||||
|
||||
printf("=================================================\n");
|
||||
printf("Test 1: Simple Loop (1000 iterations)\n");
|
||||
printf("=================================================\n");
|
||||
|
||||
int timer1 = bench_start();
|
||||
|
||||
int i = 0;
|
||||
int sum = 0;
|
||||
while (i < 1000) {
|
||||
sum = sum + i;
|
||||
i = i + 1;
|
||||
}
|
||||
|
||||
int elapsed1 = bench_end(timer1);
|
||||
char* formatted1 = bench_format_auto(elapsed1);
|
||||
|
||||
printf("Result: sum = %d\n", sum);
|
||||
printf("Time: %s (%d nanoseconds)\n\n", formatted1, elapsed1);
|
||||
|
||||
printf("=================================================\n");
|
||||
printf("Test 2: Fibonacci Calculation (fib(20))\n");
|
||||
printf("=================================================\n");
|
||||
|
||||
int timer2 = bench_start();
|
||||
int fib_result = fibonacci(20);
|
||||
int elapsed2 = bench_end(timer2);
|
||||
|
||||
char* formatted2 = bench_format_auto(elapsed2);
|
||||
|
||||
printf("Result: fibonacci(20) = %d\n", fib_result);
|
||||
printf("Time: %s (%d nanoseconds)\n\n", formatted2, elapsed2);
|
||||
|
||||
printf("=================================================\n");
|
||||
printf("Test 3: Sum of Squares (1 to 100)\n");
|
||||
printf("=================================================\n");
|
||||
|
||||
int timer3 = bench_start();
|
||||
int sum_result = compute_sum_of_squares(100);
|
||||
int elapsed3 = bench_end(timer3);
|
||||
|
||||
char* formatted3 = bench_format_auto(elapsed3);
|
||||
|
||||
printf("Result: Sum of squares = %d\n", sum_result);
|
||||
printf("Time: %s (%d nanoseconds)\n\n", formatted3, elapsed3);
|
||||
|
||||
printf("=================================================\n");
|
||||
printf("Test 4: Nested Timers\n");
|
||||
printf("=================================================\n");
|
||||
|
||||
int outer_timer = bench_start();
|
||||
|
||||
printf("Outer operation started...\n");
|
||||
|
||||
int inner_timer = bench_start();
|
||||
int k = 0;
|
||||
int product = 1;
|
||||
while (k < 50) {
|
||||
product = product + k;
|
||||
k = k + 1;
|
||||
}
|
||||
int inner_elapsed = bench_end(inner_timer);
|
||||
|
||||
printf("Inner operation completed in: %s\n", bench_format_auto(inner_elapsed));
|
||||
|
||||
int m = 0;
|
||||
while (m < 100) {
|
||||
m = m + 1;
|
||||
}
|
||||
|
||||
int outer_elapsed = bench_end(outer_timer);
|
||||
|
||||
printf("Outer operation completed in: %s\n\n", bench_format_auto(outer_elapsed));
|
||||
|
||||
printf("=================================================\n");
|
||||
printf("Test 5: Manual Format with Different Units\n");
|
||||
printf("=================================================\n");
|
||||
|
||||
int sample_time = 1234567890;
|
||||
|
||||
printf("Time: %d nanoseconds\n", sample_time);
|
||||
printf(" As nanoseconds: %s\n", bench_format(sample_time, 0));
|
||||
printf(" As microseconds: %s\n", bench_format(sample_time, 1));
|
||||
printf(" As milliseconds: %s\n", bench_format(sample_time, 2));
|
||||
printf(" As seconds: %s\n", bench_format(sample_time, 3));
|
||||
printf(" As minutes: %s\n", bench_format(sample_time, 4));
|
||||
printf(" As hours: %s\n", bench_format(sample_time, 5));
|
||||
printf(" Auto format: %s\n\n", bench_format_auto(sample_time));
|
||||
|
||||
printf("=================================================\n");
|
||||
printf("Test 6: Comparison of Algorithms\n");
|
||||
printf("=================================================\n");
|
||||
|
||||
printf("Computing fibonacci(15) multiple times...\n");
|
||||
|
||||
int timer_a = bench_start();
|
||||
int result_a = fibonacci(15);
|
||||
int elapsed_a = bench_end(timer_a);
|
||||
|
||||
int timer_b = bench_start();
|
||||
int result_b = fibonacci(15);
|
||||
int elapsed_b = bench_end(timer_b);
|
||||
|
||||
int timer_c = bench_start();
|
||||
int result_c = fibonacci(15);
|
||||
int elapsed_c = bench_end(timer_c);
|
||||
|
||||
printf("Run 1: %s (result: %d)\n", bench_format_auto(elapsed_a), result_a);
|
||||
printf("Run 2: %s (result: %d)\n", bench_format_auto(elapsed_b), result_b);
|
||||
printf("Run 3: %s (result: %d)\n", bench_format_auto(elapsed_c), result_c);
|
||||
|
||||
int avg_time = (elapsed_a + elapsed_b + elapsed_c) / 3;
|
||||
printf("Average time: %s\n\n", bench_format_auto(avg_time));
|
||||
|
||||
printf("=================================================\n");
|
||||
printf("Benchmarking Complete!\n");
|
||||
printf("=================================================\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user