4 ms·
No, not really. Languages like Nim/Rust/D/etc. should not have significantly different speeds for equivalent implementations for these kinds of benchmarks, as
by rbehrends 5y ago
No, not really.
Languages like Nim/Rust/D/etc. should not have significantly different speeds for equivalent implementations for these kinds of benchmarks, as they ultimately can be written to compile to equivalent LLVM IR and thus the same machine code.
What you're usually seeing when you see such large differences is that there are differences in the implementation of the algorithm or of a standard library function.
There's nothing about these kinds of languages that should result in inherently significant performance differences on such synthetic microbenchmarks.
- qsort 5y agoDoesn't Nim come with a runtime, though? Rust vs. C++ is entirely due to implementation differences, but isn't this more like C++ vs. Golang?
- rbehrends 5y agoA runtime isn't some sort of magic thing that inserts itself into hotspots. Several of these benchmarks are just looping over pointerfree arrays for almost all of their runtime and still show differences. Unless you call parts of the runtime, implicitly or explicitly, it shouldn't result in overhead. Allocation-heavy or write-barrier-heavy code might make a difference, but you literally have performance differences while iterating over arrays of scalars. And even then, last I benchmarked it, Nim actually compared favorably with e.g. jemalloc.
- yakubin 5y agoIt depends on the runtime. In the case of Go e.g. the compiler inserts potential "yield"-s at every function call[1]. And in the case of Swift the atomic "release" calls at ends of scopes will run regardless whether there are hot loops or not. So it all depends on the language. Also, you pointed to 3 languages with 3 different memory management strategies and 3 different toolchains (Rust is LLVM-based; Nim compiles to C and then calls a C compiler, GCC recommended; D has its own non-GCC non-LLVM compiler). It feels weird to put them in the same bag implementation-wise. [1]: <https://golangbyexample.com/goroutines-golang/ https://golangbyexample.com/goroutines-golang/> (potentially stale information)
- rbehrends 5y ago> It depends on the runtime. In the case of Go e.g. the compiler inserts potential "yield"-s at every function call[1]. > And in the case of Swift the atomic "release" calls at ends of scopes will run regardless whether there are hot loops or not. Yes, but Nim does neither. Nim does insert write barriers, but that's only if you (1) write pointers to heap-allocated memory and (2) don't use the mark-and-sweep GC, so that can't explain big performance differences for those benchmarks where you primarily iterate over arrays. > Also, you pointed to 3 languages with 3 different memory management strategies and 3 different toolchains (Rust is LLVM-based; Nim compiles to C and then calls a C compiler, GCC recommended; D has its own non-GCC non-LLVM compiler). It feels weird to put them in the same bag implementation-wise. You don't seem to be aware of it, but D actually has an LLVM-based compiler (LDC). Nim can also utilize LLVM via choosing clang as its backend. You can definitely use them to generate equivalent LLVM IR and compare that. There's nothing weird here, this allows us to rule out differences related to the backend.
- alkonaut 5y ago> There's nothing about these kinds of languages that should result in inherently significant performance differences on such synthetic microbenchmarks. I guess it depends on what significant is but I certainly hope Rust can be faster than C in many scenarios due to optimizations llvm can make with the added type information such as inferring aliasing rules.
- Ygg2 5y agoFrom my understanding, LLVM had or has many bugs around alias rules. I remember Rust emitted proper noalias IR to LLVM, only for it to be promptly ignored. https://github.com/rust-lang/rust/issues/54878 https://github.com/rust-lang/rust/issues/54878
- danielscrubs 5y ago"compile to equivalent LLVM IR". This is not true at all, not in practice and not in theory so I don't understand why it is popping up constantly. Fortran was for example faster than C in some cases before C99 added the restrict-keyword, forever changing the language.