15 ms·
A cost model for Nim
- goodpoint 4y agoNice post.
- christophilus 4y agoGood write-up. Optimizing for embedded, real-time systems is a nice way for them to cut out a little niche among similar languages. Aside: I've tinkered with Nim a long time ago (when it was called Nimrod) and thought it was pleasant. I'd be interested to hear from anyone in the HN community that has used Nim in production. What did you use it for? How was the experience?
- vlugorilla 4y agoA well-known and nice app that is build with Nim is Nitter (https://github.com/zedeus/nitter https://github.com/zedeus/nitter), a free and open source alternative Twitter front-end focused on privacy and performance.
- calvinmorrison 4y agoI found it very pleasant as well! It was pythonesque that compiled. Now pythons code makes me wants to pull my hair out. I don't know what I like anymore
- seanw444 4y agoI've tried learning it a couple times, but the syntax seems so irregular and non-uniform. It's confusing and annoying.
- cb321 4y agoNim gives a bit more choice in many dimensions than many languages -- how to manage memory, whether to use the stdlib at all for things like hash tables, and yes, also syntactic choices like several ways to call a function. This can actually be convenient in constructing a DSL for something with minimal fuss. While `func arg1 arg2` might look weird in "real" "code", it might look great inside some DSL and you can just have it be a "regular Nim invocation" instead of something special to get that. There are also compile-time superpowers like macros that just receive a parsed AST. That can be used to "re-parse" or "re-compile" external code as in https://github.com/c-blake/cligen https://github.com/c-blake/cligen. So, trade-offs like in all of life. There is even a book called The Paradox Of Choice [1]. I think there is just a spectrum/distribution of human predisposition where some like to have things "standardized & packaged up for them" while others more like to invent their own rules..and enough variation within the population that people have to learn to agree to disagree more. (EDIT: and FWIW, I think this is context-modulated - the same person could be on one end of the spectrum about gardening and the other about software.) I do feel like the syntax is far less chaotic than Perl. [1] https://en.wikipedia.org/wiki/The_Paradox_of_Choice https://en.wikipedia.org/wiki/The_Paradox_of_Choice
- olah_1 4y agoI think this is because it takes more stylistic influence from Oberon than it does from Python. https://en.wikipedia.org/wiki/Nim_(programming_language)#Influence https://en.wikipedia.org/wiki/Nim_(programming_language)#Inf...
- lordgroff 4y agoNim is a Wirthian language not a Python language, but Python always had some Wirthian touches so...
- canadianfella 4y ago
- themodelplumber 4y agoIt runs part of my billing system and was nice to use, particularly with community support which was fast and effective given their online Nim tools. Some of the debug / error messages were frustrating red herrings which IIRC I was told was an area needing improvement at least at the time.
- xigoi 4y agoAs a frequent Nim user, I can unfortunately confirm that misleading error messages are still a problem.
- nerdponx 4y agoI would gladly work at a company that used Nim as its primary language.
- nemo1618 4y ago> Most of Nim’s standard library collections are based on hashing and only offer O(1) behavior on the average case. Usually this is not good enough for a hard real-time setting and so these have to be avoided. In fact, throughout Nim’s history people found cases of pathologically bad performance for these data structures. Instead containers based on BTrees can be used that offer O(log N) operations for lookup/insertion/deletion. I'm surprised that hash maps can stray far enough from O(1) to become unusable in hard real-time. Is it because RT systems have to use lower-quality PRNGs?
- CodesInChaos 4y agoWhen targeting hard real time you want strong worst-case guarantees, not weak probabilistic arguments like "we hope the hashes are distributed well enough to achieve O(1) in practice". The malicious version of this is hash DoS, where an attacker chooses the values inserted into the hash table so they have the same hash (or at least same bucket). Randomized hashing using a secure hash mitigates this somewhat, but the attack is still possible to some degree, especially if the hash secret is long lived. Another issue is that inserting into hash tables is usually only amortized O(1), with the collection growing exponentially when it's full. So most insert operations are cheap, but occasionally you get an O(n) insertion. However it doesn't sound like this is what the article is talking about.
- cb321 4y agoWhile I agree with all you said, one can expand a bit on it. There are concrete max search depth expectations for well randomizing hash functions such as: https://www.sciencedirect.com/science/article/abs/pii/019667748790040X which is notably logarithmic - not unlike a B-Tree. When these expectations are exceeded you can at least detect a DoS attack. If you wait until such are seen, you can activate a "more random" mitigation on the fly at about the same cost as "the next resize/re-org/whatnot". All you need to do is instrument your search to track the depth. There is some example such strategy in Nim at https://github.com/c-blake/adix https://github.com/c-blake/adix for simple Robin-Hood Linear Probed tables and a formula based one from that above paper inside https://github.com/c-blake/suggest https://github.com/c-blake/suggest This is all more about the "attack" scenario than the "truly hard" real-time scenario, of course.
- pietroppeter 4y agoparticularly relevant context for this post is that Nim v2 is expected to be released within 2022, with the main change being the arc/orc memory management discussed in the blogpost. For a general review of what nim v2 will be about: - Nim 2 video by Araq at https://nim-lang.org/nimconf2022/ https://nim-lang.org/nimconf2022/ - all the details about the goals of v2 are in the roadmap RFC "Cylons are here" https://github.com/nim-lang/RFCs/issues/437 https://github.com/nim-lang/RFCs/issues/437
- PMunch 4y agoInteresting to see more focus on embedded systems. This is definitely good news for Ratel!
- pietroppeter 4y agowhich is this great project btw: https://github.com/PMunch/ratel https://github.com/PMunch/ratel what happened to that cool landing page you had?
- gavinray 4y agoNot super related to the entirety of this blogpost but this bit stuck out to me: > "If your domain is not “hard” real-time but “soft” real-time on a conventional OS, you can “pin” a thread to particular core via system.pinToCpu" This is probably one of the easiest/nicest API's I've seen for doing this in a language.
- pietroppeter 4y agounfortunately this pinToCpu seems to be discouraged or ineffective (not for nim related reason) :/ see this discussion: https://forum.nim-lang.org/t/9596#63093 https://forum.nim-lang.org/t/9596#63093
- tjoff 4y agoNot sure why it would be discouraged because of big little. Pinning to a big or pinning to a little is still a potentially useful thing.
- cb321 4y ago>Not sure why it would be discouraged pinToCPU (at least in Nim) just sets scheduling affinity, but does not hard-allocate like the Linux isolcpus boot parameter.."pin" makes it sound more powerful than it is. It is more like POSIX `nice` than POSIX `mlock`. But also, `nice` exists for a reason. Your agenda might be to do something as much as possible on a Little core which is indeed potentially useful. pinToCPU takes a cpu number and you can usually know from that number whether it is Big or Little. The real concern may be that the OS has a more global picture of system activity than any one program..and so discourage "second guessing" the scheduler. OTOH, the OS probably does not have a picture of how important timely completion of any particular thing is - honestly that could almost be end-user-provided data (much like there is a `nice` command). A lot of the time people motivate affinity just as a "use the same L1/L2 cache" for "absolute max perf", and in that sense you may be getting better perf, but over fewer cores (only the big ones) or you may not do the ahead of time work to map out big-little CPU numbers. Scheduling is also very OS-specific. So, reasoning about what Y you get when you ask for X can also be tricky in any OS-portable setting. Sometimes things are "so complicated" that people "who know" just discourage those who do not. My inclination is instead to explain what it can/cannot/does/does not do better rather than discourage its use.
- pietroppeter 4y agounrelated to the post but if you are curious on how a HN spike looks like you can follow it in real time here: https://plausible.io/nim-lang.org?period=day&date=2022-11-11 https://plausible.io/nim-lang.org?period=day&date=2022-11-11 nim recently implemented public analytics for its website and I think it is a fun thing and something I have not seen around much: https://nim-lang.org/blog/2022/11/01/this-month-with-nim.html https://nim-lang.org/blog/2022/11/01/this-month-with-nim.htm... do you know of other open source projects which have public analytics?
- gw98 4y agoHad no idea plausible.io existed. Thanks for posting the link for this. Just what I need for a project :)
- pietroppeter 4y agooh plausible works great! it is paid but open source and you can host it. very nice guys that run it. there are also other nice options out there, but this is the only one I know where it is very easy and straightforward to make your analytics public!
- ksec 4y agoLess than 10K unique visitors. Much lower than what I expected on HN front page.
- elcritch 4y agoNice to see this here! I helped edit parts of this, feel free to ask me questions. Personally I’ve quite enjoyed using Nim in RTOS and embedded systems. I believe it opens up the full power of embedded programming to non-experts. It’s hard to describe how nice the combination of ARC/ORC memory management with the TLSF allocator is for a ready-to-go real time code and systems programming. This combo gets 90-95% the speed and size of manual memory management, while being much easier to program. Generally performance and real time metrics or latency is a matter of optimizing your code, not re-writing it. Since Nim v2 integrates the allocator it also makes it trivial to debug allocations, or check for leaks.
- deleted 4y ago[deleted]
- alberth 4y agoI've always been surprised Nim hasn't taken off more. All the productivity of a language like Python but with the performance of C.
- nerdponx 4y agoI 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.