3 ms·
I have really enjoyed using it for random scripts and small programs, but it definitely is slower than plain C for simple things like "loop over lines of stdin
by nerdponx 4y ago
I have really enjoyed using it for random scripts and small programs, but it definitely is slower than plain C for simple things like "loop over lines of stdin and do some basic calculations". Of course, you also get a lot of nice abstraction, memory safety, GC, a great standard library, compiler-checked effects (!), less-noisy syntax, and a nice easy compiler CLI, and that's a tradeoff I'm happy to make. Not to mention that I would feel much more comfortable writing a bigger application in Nim than in C.
- monetus 4y agoThat slowness is tied to the GC, which you can swap in and out with others or turn off. I feel like this is a really undersold feature of the language.
- cb321 4y agoIt's a mixture of allocation, copying, and reclamation. You can actually side-step a lot of such issues in a mostly mm-agnostic way with a `var` like interface in Nim -- sticking to one initial allocation like the common pattern of caller-allocated storage in C. These days on three-level cache server CPUs the real cost of hitting virgin, uncached memory is probably worse than other pieces..DRAM latency is >10x L3, but almost everything "depends on..".
- arc776 4y ago100% my experience too. GC in Nim is a rounding error at worst and is often statically elided, anyway. Performance is almost entirely about memory access patterns and you have the same access to this as C. In other words, performance in Nim is entirely down to the algorithm used, which is a nice place to be.
- cb321 4y agoI have not found this slower-than-C to be the case. You may need to use something like `iterator getDelims` in https://github.com/c-blake/cligen/blob/master/cligen/osUt.nim https://github.com/c-blake/cligen/blob/master/cligen/osUt.ni... to manage memory with fewer copies/less alloc "more like C", though or perhaps `std/memfiles` memory mapped IO. More pithy ways to put it are that "there are no speed limits" or "Nim responds to optimization effort about as well as other low level languages like C". You can deploy SIMD intrinsics, for example. In my experience, it's not that hard to "pay only for what you use". As a more concrete thing, I have timed (yes, on one CPU, one test case, etc..many caveats) the tokenizer used in https://github.com/c-blake/bu/blob/main/rp.nim https://github.com/c-blake/bu/blob/main/rp.nim to be faster than that used by the Rust xsv. Of course, you really shouldn't tokenize a lot if it's costly/data is big, but rather save a binary answer that does not need parsing (or perhaps more accurately is natively parsed by the CPU).
- nerdponx 4y agoThis stuff honestly goes over my head and beyond my current skillset, but it's useful to know that there is no "speed limit" in the hands of someone who knows what they're doing. My experience has been with basically translating Python and shell scripts into Nim, and occasionally comparing them with my own feeble attempts at doing the same in C.
- elcritch 4y agoJust a note that the "loop over lines of stdin and do some basic calculations" use case highlights probably one of the places where it's really easy to blow up Nim's performance benefits -- string or seq copies. :/ The issue is that Nim's string library ends up making copies when doing things. It's a sane default and ensures sane behavior. However, it often leads beginner's to make slower programs, sometimes even slower than equivalent Python ones. If you used `strcopy` in C a lot, you'd get similar results. Often the solution is trivial and is just to use the `var` or `openArray[T]` variants of proc's. It's one of the points in the blog post and is crucial for good real time code. I'm hopeful the new `lent` and `view` features will make it easier to use non-copy slices on strings. That'd be nice!
- xigoi 4y agoJust to be sure, did you compile it with -d:release/-d:danger? This is a common mistake people make when benchmarking Nim.