Julia
Julia is a very interesting programming language, designed specifically for high performance scientific computing. Scientific computing emphasizes high performance, and modern language design and compiler techniques allows Julia to be used to quickly create a prototype, yet efficient enough to execute performance-critical solutions. The Julia programming language is a flexible dynamic language, appropriate for scientific and numerical computing, with performance comparable to traditional statically-typed languages.
Julia provides common linear algebra operations in the LinearAlgebra
package,
and one convenient use of Julia is to create data for tests written in other
programming languages. more…
It’s possible to call existing C functions directly from Julia, as long as the library containing the C function was compiled as a shared library, or dll. This allows Julia developers to leverage existing libraries for numerical computing written in C. Julia makes it simple to call C functions which can be called directly from Julia without any glue code, code generation, or compilation. The machine code generated by Julia’s JIT are the same as a native C call, so the overhead is the same as calling a library function from C code.
Julia appears to be a dynamically typed language, like Python, and it would not be unreasonable to expect Julia to share the performance characteristics of Python. When working with Julia I discovered that the performance sometimes even exceeds the performance of carefully optimized C code - clearly justifying the platforms claim to performance.
The table below shows the results, in seconds, after executing each of the respective
operations 1 000 000 000
times:
Test | .Net 9 | .Net Framework | Standard C++ | Optimized C++ | Julia | Python | Rust |
---|---|---|---|---|---|---|---|
IsNaN | 3,21131 | 3,6367279 | 1,1127655 | 1,0175695 | 1,41 | 188,573726 | 1.0229428 |
IsInf | 3,3915906 | 3,6948053 | 1,0464091 | 1,0140321 | 0,999 | 191,919179 | 1.0457156 |
Abs | 2,2755014 | 2,6035281 | 0,9712436 | 1,1597954 | 0,973 | 133,554733 | 0.9539125 |
FRExp | 2,2708008 | 8,6199498 | 17,5162206 | 2,4895346 | 0,98 | 320,8951 | 2.4209312 |
ModF | 2,261356 | 6,9360261 | 4,2012568 | 2,7641698 | 1,398 | 330,282251 | 1.9483226 |
Min | 2,3673176 | 6,5788681 | 0,9763737 | 1,0012508 | 1,456 | 230,150583 | 0.9530636 |
Max | 2,3819487 | 6,1213893 | 0,9706261 | 0,9790643 | 1,223 | 234,857767 | 0.9481684 |
Ceil | 2,3127194 | 7,261466 | 1,1667381 | 0,9854143 | 1,148 | 288,997075 | 4.8385903 |
Floor | 2,2406476 | 6,5273658 | 1,1646673 | 0,9711043 | 1,147 | 299,056741 | 4.2593385 |
Trunc | 2,8116986 | 7,6517926 | 8,1095757 | 0,9861945 | 1,167 | 211,218895 | 8.2184693 |
Round | 2,2979082 | 4,2840166 | 11,503602 | 1,0072632 | 1,213 | 291,214887 | 11.7508667 |
Lerp | 1,2302819 | 2,1986549 | 2,3439255 | 1,1662787 | 1,222 | 197,52626 | 1.1492095 |
Sin | 7,8218807 | 32,733977 | 7,4981783 | 7,3220644 | 8,385 | 210,231034 | 8.0410636 |
ASin | 11,4004879 | 13,6180039 | 10,6491442 | 6,709916 | 6,386 | 217,004373 | 11.1567682 |
Cos | 8,4738403 | 32,685339 | 7,0921574 | 7,0395165 | 8,541 | 209,697392 | 8.4506613 |
ACos | 11,9971425 | 14,1201149 | 10,8390355 | 5,7188627 | 6,216 | 217,970242 | 11.4727166 |
Tan | 11,9070397 | 41,6371849 | 10,6903641 | 10,6894836 | 12,331 | 223,032492 | 11.0177146 |
ATan | 8,3657106 | 42,5579887 | 7,1827557 | 6,4776865 | 7,404 | 218,877134 | 7.3598513 |
ATan2 | 19,4174499 | 41,721993 | 25,4644532 | 15,4972265 | 14,985 | 274,691577 | 18.2896109 |
Sqrt | 4,7177178 | 2,8413529 | 1,4642421 | 1,4638211 | 1,455 | 203,658153 | 1.4675657 |
Total | 113,1543502 | 288,0305448 | 131,9637345 | 76,4602488 | 80,039 | 4693,409594 | 116.7654832 |
Out of the box, Julia outperforms the standard C++ implementation of the tests by 64
%.
Getting C++ to perform as fast as Julia, took a bit of an effort, as this required carefully optimized versions of several of the standard math functions to get comparable performance.
Links to the code used to perform the tests: