Comment by galangalalgol

Comment by galangalalgol a day ago

4 replies

What language do people considering c as an option for a new project consider? Rust is the obvious one we aren't going to discuss because then we won't be able to talk about anything else, Zig is probably almost as well loved and defended, but it isn't actually memory safe, just much easier to be memory safe. As you say, c# and go, also maybe f# and ocaml if we are just writing simple c style stuff none of those would look all that different. Go jhs some ub related to concurrency that people run into, but most of these simple utilities are either single threaded or fine grained parallel which is pretty easy to get right. Julia too maybe?

summarity a day ago

In terms of GC quality, Nim comes to mind.

  • galangalalgol a day ago

    I keep ignoring nim for some reason. How fast is it with all the checks on? The benchmarks for it julia, and swift typically turn off safety checks, which is not how I would run them.

    • cb321 14 hours ago

      Since anything/0 = infinity, these kinds of things always depend upon what programs do and as a sibling comment correctly observes how much they interfere with SIMD autovectorization and sevral other things.

      That said, as a rough guideline, nim c -d=release can certainly be almost the same speed as -d=danger and is often within a few (single digits) percent. E.g.:

          .../bu(main)$ nim c -d=useMalloc --panics=on --cc=clang -d=release -o=/t/rel unfold.nim
          Hint: mm: orc; opt: speed; options: -d:release
          61608 lines; 0.976s; 140.723MiB peakmem; proj: .../bu/unfold.nim; out: /t/rel [SuccessX]
          .../bu(main)$ nim c -d=useMalloc --panics=on --cc=clang -d=danger -o=/t/dan unfold.nim
          Hint: mm: orc; opt: speed; options: -d:danger
          61608 lines; 2.705s; 141.629MiB peakmem; proj: .../bu/unfold.nim; out: /t/dan [SuccessX]
          .../bu(main)$ seq 1 100000 > /t/dat
          .../bu(main)$ /t
          /t$ re=(chrt 99 taskset -c 2 env -i HOME=$HOME PATH=$PATH)
          /t$ $re tim "./dan -n50 <dat>/n" "./rel -n50 <dat>/n"
          225.5 +- 1.2 μs (AlreadySubtracted)Overhead
          4177 +- 15 μs   ./dan -n50 <dat>/n
          4302 +- 17 μs   ./rel -n50 <dat>/n
          /t$ a (4302 +- 17)/(4177 +- 15)
          1.0299 +- 0.0055
          /t$ a 299./55
          5.43636... # kurtosis=>5.4 sigmas is not so significant
      
      Of course, as per my first sentence, the best benchmarks are your own applications run against your own data and its idiosyncratic distributions.

      EDIT: btw, /t -> /tmp which is a /dev/shm bind mount while /n -> /dev/null.

    • adgjlsfhk1 a day ago

      In Julia, at least, bounds checks tend to be a pretty minor hit (~20%) unless the bounds check gets in the way of vectorization