Skip to content

Instantly share code, notes, and snippets.

@szapp
Last active August 10, 2025 12:31
Show Gist options
  • Select an option

  • Save szapp/89da305ad3301befe8f7b7d474892c68 to your computer and use it in GitHub Desktop.

Select an option

Save szapp/89da305ad3301befe8f7b7d474892c68 to your computer and use it in GitHub Desktop.
Daedalus performance benchmark (PBM) to compare two implementations (e.g. Daedalus vs. machine code) based on MEM_Benchmark.
/*
* Performance benchmark (PBM) to compare two implementations (e.g. Daedalus vs. machine code) based on MEM_Benchmark.
* Adjust the implementations `pbm_impl_A` and `pbm_impl_B` and compare their performance with `pbm_run()`.
*/
const int pbm_loop_num = 10000;
func int pbm_impl_A() {
// Example: Loop that sums all numbers (Daedalus)
var int sum; sum = 0;
repeat(i, pbm_loop_num); var int i;
sum += i;
end;
return sum;
};
func int pbm_impl_B() {
// Example: Loop that sums all numbers (Machine code)
if (!code) {
const int code = 0;
const int ret = 0;
ASM_Open(23+1);
ASM_2(51505); // xor ecx,ecx
ASM_2(49201); // xor eax,eax
ASM_1(186); ASM_4(pbm_loop_num); // mov edx,pbm_loop_num
// start:
ASM_2(53561); // cmp ecx,edx
ASM_2(1405); // jge end
ASM_2(51201); // add eax,ecx
ASM_1(65); // inc ecx
ASM_2(63467); // jmp start
// end:
ASM_1(163); ASM_4(_@(ret)); // mov [ret],eax
code = ASM_Close();
};
ASM_Run(code);
return ret;
};
/* -- INTERNALS -- */
/* Wrapper functions to pop return value */
func void pbm_wrap_A() {
var int ret; ret = pbm_impl_A();
};
func void pbm_wrap_B() {
var int ret; ret = pbm_impl_B();
};
func int pbm_empty() { return 1; };
func void pbm_wrap_empty() {
var int ret; ret = pbm_empty(); // Emulate overhead from pushing and popping
};
/* Arithmetic helper functions */
func int pbm_sum(var int valPtr, var int n) {
var int val[255]; MEM_CopyWords(valPtr, _@(val), n);
var int sum; sum = FLOATNULL;
repeat(i, n); var int i;
sum = addf(sum, MEM_ReadStatArr(val, i));
end;
return sum;
};
func int pbm_avg(var int valPtr, var int n) {
return divf(pbm_sum(valPtr, n), mkf(n));
};
func int pbm_std(var int valPtr, var int n) {
var int val[255]; MEM_CopyWords(valPtr, _@(val), n);
var int avg; avg = pbm_avg(valPtr, n);
repeat(i, n); var int i;
var int v; v = MEM_ReadStatArr(val, i);
var int dev; dev = sqrf(subf(v, avg));
MEM_WriteStatArr(val, i, dev);
end;
var int vari; vari = pbm_avg(_@(val), n);
return sqrtf(vari);
};
/* Format the results */
func string pbm_format(var int f) {
// Format to ".2f"
var string full; var string dec;
full = STR_Split(toStringf(f), ".", 0);
dec = STR_Prefix(STR_Split(toStringf(f), ".", 1), 2);
return ConcatStrings(ConcatStrings(full, "."), dec);
};
func string pbm_result_str(var int avg, var int std, var string unit) {
var string msg; msg = "";
msg = ConcatStrings(msg, pbm_format(avg));
if (std) {
msg = ConcatStrings(msg, "+-");
msg = ConcatStrings(msg, pbm_format(std));
};
msg = ConcatStrings(msg, " ");
msg = ConcatStrings(msg, unit);
return msg;
};
/* Main function */
func void pbm_run() {
// Running several iterations multiple times
const int NUM_ITER = 1000; // Increase for more accurate estimation (careful with high numbers)
const int MUM_REPEAT = 5; // Increase for robustness against OS interruption
// Warm up for cold start
pbm_wrap_A();
pbm_wrap_A();
pbm_wrap_B();
pbm_wrap_B();
pbm_wrap_empty();
pbm_wrap_empty();
// Verify outputs (twice)
if (pbm_impl_A() != pbm_impl_B()) || (pbm_impl_A() != pbm_impl_B()) {
MEM_AssertFail("Result does not match across implementations.");
return;
};
var string msg; msg = "Running benchmark with ";
msg = ConcatStrings(msg, IntToString(MUM_REPEAT));
msg = ConcatStrings(msg, " x ");
msg = ConcatStrings(msg, IntToString(NUM_ITER));
msg = ConcatStrings(msg, " iterations. Please wait...");
MEM_Info(msg);
// Benchmark multiple times to catch drift or OS interrupts
var int overhead; overhead = MEM_BenchmarkMMS_N(pbm_wrap_empty, NUM_ITER);
var int tic_A[MUM_REPEAT];
var int tic_B[MUM_REPEAT];
var int est;
repeat(i, MUM_REPEAT); var int i;
est = mkf(MEM_BenchmarkMMS_N(pbm_wrap_A, NUM_ITER) - overhead);
MEM_WriteStatArr(tic_A, i, est);
est = mkf(MEM_BenchmarkMMS_N(pbm_wrap_B, NUM_ITER) - overhead);
MEM_WriteStatArr(tic_B, i, est);
end;
var int num_iter_f; num_iter_f = mkf(NUM_ITER);
var int avg_A; avg_A = divf(pbm_avg(_@(tic_A), MUM_REPEAT), num_iter_f);
var int std_A; std_A = divf(pbm_std(_@(tic_A), MUM_REPEAT), num_iter_f);
var int avg_B; avg_B = divf(pbm_avg(_@(tic_B), MUM_REPEAT), num_iter_f);
var int std_B; std_B = divf(pbm_std(_@(tic_B), MUM_REPEAT), num_iter_f);
MEM_Info("");
MEM_Info("BENCHMARK RESULTS");
MEM_Info(ConcatStrings(" Implementation A: ", pbm_result_str(avg_A, std_A, "ns")));
MEM_Info(ConcatStrings(" Implementation B: ", pbm_result_str(avg_B, std_B, "ns")));
MEM_Info(ConcatStrings("Subtracted overhead: ", pbm_result_str(fracf(overhead, NUM_ITER), 0, "ns")));
MEM_Info("");
MEM_InfoBox("Benchmarking complete");
};
@szapp
Copy link
Author

szapp commented Aug 10, 2025

Example output in zSpy.

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment