4 ms·
A 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
by rbehrends 5y ago
A 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.