# Julia vs Zig surprise

**URL:** <https://discourse.julialang.org/t/julia-vs-zig-surprise/74540>\
**Category:** Performance\
**Tags:** llvm\
**Created:** [January 13, 2022, 10:45am UTC](https://discourse.julialang.org/t/julia-vs-zig-surprise/74540 "2022-01-13T10:45:47Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![Bardo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bardo/32/21601_2.png) [@Bardo](https://discourse.julialang.org/u/Bardo)\
**Post date:** [January 13, 2022, 10:45am UTC](https://discourse.julialang.org/t/julia-vs-zig-surprise/74540/1 "2022-01-13T10:45:47Z")

</div>

Recently ran into two performance comparisons including Julia.

[THE LINEAR ALGEBRA MAPPING PROBLEM. CURRENT STATE  
OF LINEAR ALGEBRA LANGUAGES AND LIBRARIES.](https://arxiv.org/pdf/1911.09421.pdf)  
shows that using `BLAS` for dense matrix operations, all libraries or languages like `Armadillo, Eigen, Julia, Matlab, NumPy, Octave, R` give comparable performance, within a small margin.

The actual surprise comes here:

This [site](https://programming-language-benchmarks.vercel.app/) benchmarks programming languages on exemplary tasks. Interesting are the [Julia VS Zig benchmarks](https://programming-language-benchmarks.vercel.app/julia-vs-zig), since Zig, as Julia, uses `LLVM` as optimizing compiler backend.  
While `Zig `can be faster than `Julia `by a margin, it consumes incredibly little memory.

Something to learn?

## [Spectral-norm](https://programming-language-benchmarks.vercel.app/problem/spectral-norm)

### Input: 8000

| lang | code | time | stddev | peak-mem | time(user) | time(kernel) | compiler/runtime |
| --- | --- | --- | --- | --- | --- | --- | --- |
| [zig](https://programming-language-benchmarks.vercel.app/zig) | [2.zig](https://github.com/hanabi1224/Programming-Language-Benchmarks/blob/main/bench/algorithm/spectral-norm/2.zig) | 895ms | 1.9ms | 0.3MB | 1720ms | 0ms | zig 0.10.0-dev |
| [julia](https://programming-language-benchmarks.vercel.app/julia) | [2.jl](https://github.com/hanabi1224/Programming-Language-Benchmarks/blob/main/bench/algorithm/spectral-norm/2.jl) | 1269ms | 5.6ms | 198.7MB | 2133ms | 140ms | julia 1.7.1 |
| [julia](https://programming-language-benchmarks.vercel.app/julia) | [3.jl](https://github.com/hanabi1224/Programming-Language-Benchmarks/blob/main/bench/algorithm/spectral-norm/3.jl) | 2051ms | 36ms | 203.3MB | 3577ms | 147ms | julia 1.7.1 |
| [zig](https://programming-language-benchmarks.vercel.app/zig) | [1.zig](https://github.com/hanabi1224/Programming-Language-Benchmarks/blob/main/bench/algorithm/spectral-norm/1.zig) | 3848ms | 0.6ms | 0.2MB | 3840ms | 0ms | zig 0.10.0-dev |

### Input: 4000

| lang | code | time | stddev | peak-mem | time(user) | time(kernel) | compiler/runtime |
| --- | --- | --- | --- | --- | --- | --- | --- |
| [zig](https://programming-language-benchmarks.vercel.app/zig) | [2.zig](https://github.com/hanabi1224/Programming-Language-Benchmarks/blob/main/bench/algorithm/spectral-norm/2.zig) | 236ms | 4.1ms | 0.2MB | 420ms | 0ms | zig 0.10.0-dev |
| [julia](https://programming-language-benchmarks.vercel.app/julia) | [2.jl](https://github.com/hanabi1224/Programming-Language-Benchmarks/blob/main/bench/algorithm/spectral-norm/2.jl) | 614ms | 3.0ms | 195.2MB | 860ms | 130ms | julia 1.7.1 |
| [julia](https://programming-language-benchmarks.vercel.app/julia) | [3.jl](https://github.com/hanabi1224/Programming-Language-Benchmarks/blob/main/bench/algorithm/spectral-norm/3.jl) | 832ms | 5.3ms | 198.4MB | 1200ms | 157ms | julia 1.7.1 |
| [zig](https://programming-language-benchmarks.vercel.app/zig) | [1.zig](https://github.com/hanabi1224/Programming-Language-Benchmarks/blob/main/bench/algorithm/spectral-norm/1.zig) | 956ms | 7.2ms | 0.1MB | 947ms | 0ms | zig 0.10.0-dev` |

---

<div class="post-metadata">

**Author:** ![Steven\_Sagaert](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/steven_sagaert/32/29578_2.png) [@Steven\_Sagaert](https://discourse.julialang.org/u/Steven_Sagaert)\
**Post date:** [January 13, 2022, 1:19pm UTC](https://discourse.julialang.org/t/julia-vs-zig-surprise/74540/2 "2022-01-13T13:19:22Z")

</div>

Crystal also uses a lot less memory than Julia but more than Zig (expected since it’s GC, not manual memory management) and is also fast.

> **[Crystal VS Julia benchmarks, Which programming language or compiler is faster](https://programming-language-benchmarks.vercel.app/crystal-vs-julia)**
>
> benchmarks,benchmark,performance,binarytrees,coro-prime-sieve,edigits,fannkuch-redux,fasta,helloworld,http-server,lru,mandelbrot,merkletrees,nbody,nsieve,pidigits,regex-redux,spectral-norm,Crystal,Crystal lang,Julia,Julia lang

> **[Crystal VS Zig benchmarks, Which programming language or compiler is faster](https://programming-language-benchmarks.vercel.app/crystal-vs-zig)**
>
> benchmarks,benchmark,performance,binarytrees,coro-prime-sieve,edigits,fannkuch-redux,fasta,helloworld,http-server,lru,mandelbrot,merkletrees,nbody,nsieve,pidigits,regex-redux,spectral-norm,Crystal,Crystal lang,Zig,Zig lang

---

<div class="post-metadata">

**Author:** ![ImreSamu](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/imresamu/32/20677_2.png) [@ImreSamu](https://discourse.julialang.org/u/ImreSamu)\
**Post date:** [January 13, 2022, 1:38pm UTC](https://discourse.julialang.org/t/julia-vs-zig-surprise/74540/3 "2022-01-13T13:38:53Z")

</div>

> [@Bardo](#):
>
> since Zig, as Julia, uses `LLVM` as optimizing compiler backend.

**different LLVM** versions!

- Julia 1.7.1 - LLVM-12.0.1
- zig 0.10.0-dev - LLVM 13.?

imho :

- the “zig 0.10.0-dev” is unreleased ( [the latest release is 0.9.0](https://github.com/ziglang/zig/releases) )
- so the correct benchmark will be with [Julia Nightly builds](https://julialang.org/downloads/nightlies/)

EDIT:

other important info - some LLVM works on the roadmaps!

- like : **“Separate LLVM/codegen from runtime”** / etc.

 ![](https://global.discourse-cdn.com/julialang/original/3X/8/7/871d97526d25e1565e54d42df349ba7e63062e42.jpeg)  
see : [https://www.youtube.com/watch?v=IlFVwabDh6Q&t=537s](https://www.youtube.com/watch?v=IlFVwabDh6Q&t=537s)

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [January 13, 2022, 1:48pm UTC](https://discourse.julialang.org/t/julia-vs-zig-surprise/74540/4 "2022-01-13T13:48:47Z")

</div>

Zig does not have a runtime etc so it isn’t surprising Julia is using more memory?

---

<div class="post-metadata">

**Author:** ![Steven\_Sagaert](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/steven_sagaert/32/29578_2.png) [@Steven\_Sagaert](https://discourse.julialang.org/u/Steven_Sagaert)\
**Post date:** [January 13, 2022, 2:01pm UTC](https://discourse.julialang.org/t/julia-vs-zig-surprise/74540/5 "2022-01-13T14:01:24Z")

</div>

No but Crystal does have a runtime and still uses a lot less memory. Chalk it up to static vs dynamic typing?

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [January 13, 2022, 2:18pm UTC](https://discourse.julialang.org/t/julia-vs-zig-surprise/74540/6 "2022-01-13T14:18:50Z")

</div>

Considering the comment in [2.jl](https://github.com/hanabi1224/Programming-Language-Benchmarks/blob/main/bench/algorithm/spectral-norm/2.jl):

> The expanded form of Printf.@printf macro takes a significant time to compile, accounting for 25% of the total program runtime. Base.Ryu.writefixed(::Float64, ::Int) should already be compiled into the default system image.

The difference may come from compilation times, no?

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [January 13, 2022, 3:17pm UTC](https://discourse.julialang.org/t/julia-vs-zig-surprise/74540/7 "2022-01-13T15:17:55Z")

</div>

> [@Steven\_Sagaert](#):
>
> No but Crystal does have a runtime and still uses a lot less memory.

Does Crystal have a 170 MB system image that it loads on startup?

---

<div class="post-metadata">

**Author:** ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)\
**Post date:** [January 13, 2022, 3:23pm UTC](https://discourse.julialang.org/t/julia-vs-zig-surprise/74540/8 "2022-01-13T15:23:44Z")

</div>

The big difference is that Julia supports `eval` (and defining new methods at runtime) which neither crystal nor zig do as far as I’m aware. This means that the Julia runtime currently has to include LLVM so code generated at runtime can be compiled.

---

<div class="post-metadata">

**Author:** ![Steven\_Sagaert](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/steven_sagaert/32/29578_2.png) [@Steven\_Sagaert](https://discourse.julialang.org/u/Steven_Sagaert)\
**Post date:** [January 13, 2022, 3:30pm UTC](https://discourse.julialang.org/t/julia-vs-zig-surprise/74540/9 "2022-01-13T15:30:35Z")

</div>

luckily no.

---

<div class="post-metadata">

**Author:** ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)\
**Post date:** [January 13, 2022, 5:00pm UTC](https://discourse.julialang.org/t/julia-vs-zig-surprise/74540/10 "2022-01-13T17:00:14Z")

</div>

I’m sorry, but this is not very surprising given how the test is setup.

Notice that the build step for Julia is just copying the source file over:

[https://github.com/hanabi1224/Programming-Language-Benchmarks/blob/main/bench/bench\_julia.yaml#L40-L49](https://github.com/hanabi1224/Programming-Language-Benchmarks/blob/main/bench/bench_julia.yaml#L40-L49)

The build step for Zig is actually compiling the code:

[https://github.com/hanabi1224/Programming-Language-Benchmarks/blob/main/bench/bench\_zig.yaml#L40-L48](https://github.com/hanabi1224/Programming-Language-Benchmarks/blob/main/bench/bench_zig.yaml#L40-L48)

Thus, the Julia benchmarks include code compilation.

---

<div class="post-metadata">

**Author:** ![RoyiAvital](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/royiavital/32/571_2.png) [@RoyiAvital](https://discourse.julialang.org/u/RoyiAvital)\
**Post date:** [January 13, 2022, 6:05pm UTC](https://discourse.julialang.org/t/julia-vs-zig-surprise/74540/11 "2022-01-13T18:05:31Z")

</div>

The article / paper you linked to is really interesting: [The Linear Algebra Mapping Problem. Current State of Linear Algebra Languages and Libraries](https://arxiv.org/abs/1911.09421).

It shows some patterns which can be optimized.  
For instance:

 ![image](https://global.discourse-cdn.com/julialang/original/3X/b/5/b5786b58d9a1efdb7b814868e23c86ef78ebbe66.png)

---

<div class="post-metadata">

**Author:** ![Bardo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bardo/32/21601_2.png) [@Bardo](https://discourse.julialang.org/u/Bardo)\
**Post date:** [January 13, 2022, 7:09pm UTC](https://discourse.julialang.org/t/julia-vs-zig-surprise/74540/12 "2022-01-13T19:09:25Z")

</div>

> [@RoyiAvital](#):
>
> It shows some patterns which can be optimized.

Raised an issue  
[Improve matrix multiplication and solvers · Issue #43799 · JuliaLang/julia (github.com)](https://github.com/JuliaLang/julia/issues/43799)

---

<div class="post-metadata">

**Author:** ![bjarthur](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bjarthur/32/9638_2.png) [@bjarthur](https://discourse.julialang.org/u/bjarthur)\
**Post date:** [January 15, 2022, 2:34pm UTC](https://discourse.julialang.org/t/julia-vs-zig-surprise/74540/13 "2022-01-15T14:34:57Z")

</div>

excuse my ignorance here, but the paper does not define what SPD means so far as i can tell.

if SPD is a reference to symmetric packed matrices, then i have a new package in the works that might help. ~~PackedArrays.jl~~ [EDIT: now [SymmetricFormats.jl](https://github.com/JaneliaSciComp/SymmetricFormats.jl) due to small Damerau-Levenshtein distance with PartedArrays.jl 🙂 ], which is still currently private, but for which i can add some documentation too and make public next week, defines a `SymmetricPacked` type to mirror `LinearAlgebra.Symmetric`. the columns of either the upper or lower triangle are concatenated into a vector just like BLAS expects them to be.

i have also gotten merged a couple PRs of mine related to packed symmetric matrices recently. BLAS has many other subroutines which input packed arrays, but `spmv` and `spr` were the only ones i needed:

[https://github.com/JuliaLang/julia/pull/42830](https://github.com/JuliaLang/julia/pull/42830)

[https://github.com/JuliaGPU/CUDA.jl/pull/1248](https://github.com/JuliaGPU/CUDA.jl/pull/1248)

---

<div class="post-metadata">

**Author:** ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)\
**Post date:** [January 15, 2022, 3:36pm UTC](https://discourse.julialang.org/t/julia-vs-zig-surprise/74540/14 "2022-01-15T15:36:02Z")

</div>

I think spd is semi-positive definite

---

<div class="post-metadata">

**Author:** ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)\
**Post date:** [January 15, 2022, 3:39pm UTC](https://discourse.julialang.org/t/julia-vs-zig-surprise/74540/15 "2022-01-15T15:39:19Z")

</div>

Or symmetric positive definite.

---

<div class="post-metadata">

**Author:** ![viralbshah](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/viralbshah/32/54_2.png) [@viralbshah](https://discourse.julialang.org/u/viralbshah)\
**Post date:** [January 15, 2022, 3:46pm UTC](https://discourse.julialang.org/t/julia-vs-zig-surprise/74540/16 "2022-01-15T15:46:50Z")

</div>

I only knew of SPD as symmetric positive definite - so that you can do Cholesky.

---

<div class="post-metadata">

**Author:** ![gbellomia](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gbellomia/32/19443_2.png) [@gbellomia](https://discourse.julialang.org/u/gbellomia)\
**Post date:** [January 16, 2022, 4:29pm UTC](https://discourse.julialang.org/t/julia-vs-zig-surprise/74540/17 "2022-01-16T16:29:38Z")

</div>

It’s defined actually, look at Table1 caption: Symmetric Positive Definite.
