Comparing Python, Zig, and C

Hi everyone!

Since my last post on interacting with C from Zig, I’ve been excited to play around more with the C ABI. This time I decided to try to compare the performance between algorithms implemented in C, Python, and Zig, as a fun exercise (and to boast about performance of the languages I love). So far I’ve only implemented Quick Sort, but am excited about the results.

On a set of 1000 random data points, over the course of 100 tests, it’s obvious that C and Zig outperform Python by a landslide. What isn’t so obvious is the result of Zig being faster than C. I know this method of testing isn’t absolute and bullet-proof, but its a fun exercise and I’m sure someone would like to play around with the code to see what results they can get.

By default zig compiles for your processor (cpu=native). You can use the cpu=baseline that means a really old cpu.

The build commands are:

  • zig build -Dcpu=baseline
  • zig build-exe -mcpu=baseline
1 Like

Regarding sort, you might also be interested to compare qsort from libc vs std.mem.sortUnstable from Zig.

1 Like

Just a copy-past from here:

original c++ version (with -O3 g++ option)
$ time ./fpaq0p c ~/CC/enwik8 zz
enwik8 (100000000 bytes) -> zz (61457810 bytes) in 10.98 s.

real    0m11,093s
user    0m10,831s
sys     0m0,172s

zig
$ time ./fpaq0p c ~/CC/enwik8 zz
enwik8 (100000000 bytes) -> zz (61457810 bytes) in 8890 msec

real    0m8,893s
user    0m8,753s
sys     0m0,136s

Idk if copy paste is a fair assessment of my code, considering I also test python. Moreover, i have a framework in place for testing more than just a single algorithm :saluting_face:

Hey cool project, just wanted to share this if you want to improve the build script a little :slight_smile:

    const run_step = b.step("run", "Run the test comparison.");
    run_step.dependOn(&zig_quicksort_artifact.step);
    run_step.dependOn(&c_quicksort_artifact.step);
    const algorithm = &.{ "c_quicksort", "zig_quicksort", "py_quicksort" };
    inline for (algorithm) |algo| {
        const run_args: []const []const u8 = &.{ "python3", "./app.py", "--num-iterations=10", "--num-elements=100000", "--algorithm=" ++ algo };
        const system_cmd = b.addSystemCommand(run_args);
        run_step.dependOn(&system_cmd.step);
    }

to directly run the comparison if you want, also you might want to check your build dll import logic in python, because the directories were wrong, aka they were not in bin but in lib for me so I had to change it (as well as the extension but I was expecting that).

2 Likes

Awesome idea! I’m still learning the build system and this tip is great. I’ll definitely be trying this out, thanks for the suggestion

1 Like