5/26/2026 at 3:30:22 AM
I would summarize it thusly: Rust is roughly as performant as C. This matches my experience and Rust is more ergonomic than C in many regards. The caveat is that modern C++ is notably more performant than C and by implication Rust. This also matches my experience for both C and Rust.I think most of this is attributable to the ergonomics of compile-time expressiveness. C++ can effortlessly do things that require mountains of ugly boilerplate and macros in C or Rust. In principle they can express the same things but no one wants to write or deal with that ugly boilerplate so the equivalency is never realized in real code bases.
Zig is interesting because it slots in as a C-like language with a competent and expressive compile-time story. I don’t use Zig but I recognize its game.
by jandrewrogers
5/26/2026 at 3:35:39 AM
Is C++ more performant than C? I find this hard to believe. C++ does not have any construct that cannot be replicated, or is not common, in C. The only candidate is using virtualization and void* pointers instead of monomorphized generics which some C code does for the lack of better options, but that's not a problem in Rust as well.If anything, Rust has the potential to be more performant than C due to its aliasing rules (C has `restrict` but it's rarely used, standard C++ does not have even that). The current perf stats show it does make Rust code faster but just a little bit, although we don't utilize the full optimization potential currently (LLVM does not do many possible optimizations here, and `noalias` is weaker than Rust's aliasing rules). It can also affect autovectorization, and if it does the effect could be dramatic.
by afdbcreid
5/26/2026 at 4:19:27 AM
Modern C++ metaprogramming materially impacts performance in practice. I’ve done performance engineering for decades in both C and modern C++ and I would assert that the difference isn’t arguable.The poor applicability of auto-vectorization is another area where C++ is strong. You can transparently codegen e.g. AVX512 from intrinsics directly in C++ in contexts that would be opaque to auto-vectorization and difficult to generalize in C. This allows you to get some degree of “auto-vectorization” where the compiler can’t see it because it works at the wrong level of abstraction.
With sufficiently heroic efforts you can write C that matches the performance of C++. I’m not arguing that. Virtually no one writes C to that standard, including myself when I was writing high-performance C because the effort was too high, so it is a bit of a strawman.
It is the difference between theory and practice. All code bases have a finite budget. C++ can do a lot more optimization in the same budget as C.
by jandrewrogers
5/26/2026 at 5:33:32 AM
So youre saying the metaprogramming facilities of C++ allow the compiler to better optimise high level human readable code more effectively than C. Thats a fair point and one I'd never even thought of before, I always thought C was faster because of things like v-tables and all that stuff.by globalnode
5/26/2026 at 5:56:38 AM
In C++, nobody would want or need to use virtual functions in high-performance computational applications, while in the C language structures with virtual function tables that are accessed explicitly by the programmer are in widespread use wherever suitable, for instance in many popular open-source C programs, like the Linux kernel or the debugger gdb.So the existence of virtual function tables is not a differentiator between C++ and C.
The data types with virtual function tables are just the implementation method for sum types that is dual to tagged unions. Both virtual function tables and tagged unions can be implemented in C and in most other programming languages that do not have intrinsic support for them, but they require explicit boilerplate code for invoking the virtual functions or for testing the union tags.
Which is the better of these 2 variants depends on the application. In high-performance computations, one does not use ambiguous data types, so normally none of these 2 is used. There are a few object-oriented programming languages where "everything is an object", i.e. any kind of data includes a virtual table pointer, but those are just incomplete programming languages, which do not have all the data types needed in practice, like also many early programming languages that had a unique data type, e.g. the original LISP I, which had only linked lists and no arrays, etc. C++ at least is a complete language, in which any kind of data type can be implemented, without overheads.
As you said previously, C has few restrictions in what it can do, so in theory it is almost always possible to write a C program almost exactly equivalent with any program written in another language, matching its speed, even if that may require a significant reorganization of the code, not a line to line translation.
Nevertheless, as the other poster said, the effort needed to write that equivalent program may be so high that it is not a realistic solution.
So in practice it is not unusual that at similar programming efforts a higher-level language like C++ frequently allows writing a faster program than C.
by adrian_b
5/26/2026 at 7:01:59 AM
> while in the C language structures with virtual function tables that are accessed explicitly by the programmer are in widespread use wherever suitable, for instance in many popular open-source C programs, like the Linux kernel or the debugger gdbFor dynamic dispatch there is absolutely no difference between using a jump table in C and virtual method tables in C++. If the compiler can infer the target address at compile time, it will not go through an indirect call, e.g.:
https://www.godbolt.org/z/as8ehGhv3
And for 'static dispatch' there's no difference between a C++ method call and a direct C function call (since for static dispatch the caller needs to 'know' the target function either way).
by flohofwoe
5/26/2026 at 7:11:21 PM
With the difference that in C++ you can easily generate such call table at compile time without macro soup, while having it type checked.Even better if assuming C++26.
by pjmlp
5/26/2026 at 6:00:17 AM
For example, you can do loop unrolling using C++ template meta-programming.https://cpplove.blogspot.com/2012/07/a-generic-loop-unroller...
Of course, nothing beats hand written ffmpeg-style assembly which takes into account optimal register allocation, instruction scheduling, cache alignment, etc. for specific processor architectures.
by leonidasrup
5/26/2026 at 6:57:33 AM
Careful. That article is from 2012 and compile time unrolling was more useful back then. Today or can actually be harmful as it hides strong hints about the loop from the optimizer. Our code that did this fared worse than a loop, because no optimizer-writer expected unrolled loops.by jeffreygoesto
5/26/2026 at 10:08:35 AM
Yes, to a degree. For example, if you look into Eigen, the math library, you'll notice that it's mostly header-only and heavily templated. Writing all that by hand in C would be possible, but incredibly time-consuming unless you'd rely on some pretty incredible macro-magistry.by nnevatie
5/26/2026 at 9:06:37 AM
> So youre saying the metaprogramming facilities of C++ allow the compiler to better optimise high level human readable code more effectively than C.The metaprogramming facilities of C++ allow the programmer to more effectively optimise than they would have the patience to do in C.
The compiler's own optimisations don't directly benefit from the metaprogramming facilities in this sense. What they do is let the programmer break high level constructs down to codegen that the compiler can optimise
And you could do the same things by hand in C or Rust, but it would be tedious in the extreme, and you'd probably find yourself adopting external codegen tools
by swiftcoder
5/26/2026 at 8:02:37 PM
[flagged]by greenavocado
5/26/2026 at 8:38:42 AM
> I find this hard to believe. C++ does not have any construct that cannot be replicated, or is not common, in C.But this is not a valid argument, as all languages are Turing complete, and most modern languages can do low level stuff at optimum speeds. As an extreme example, in Java, you could just allocate a large chunk of memory and run an allocator inside of it and sidestep the GC entirely.
With a programming language the question is thus not what can you do with it and how fast can it run with infinite effort, but what are the ergonomics, and what performance will you get in practice.
by amelius
5/26/2026 at 3:47:26 AM
C++ you get templated generic algorithms that in practice no one really does with C because macros suck too much. So in C typically you'd have a runtime generic routine that doesn't inline. A classic example here is qsort() vs std::sort().by loeg
5/26/2026 at 6:46:59 AM
> So in C typically you'd have a runtime generic routine that doesn't inline.With LTO you get many of the same advantages as C++ template code, there's nothing magic about C++ template optimizations, it's all about whether the compiler can see all function bodies in a call hierarchy.
by flohofwoe
5/26/2026 at 7:51:43 AM
LTO cannot change the layout of structs. For something like a hash map implementation, it matters whether inner nodes store a pointer to the key and value, or whether it stores a pointer to each. To achieve this in C, you have no other options than emulating templates using macros.by simonask
5/26/2026 at 8:31:18 AM
The question is whether a hash-map implementation that works on a general `[key, index]` item and where index references at separate array of values isn't actually better for some access patterns ;)And of course the other alternative to macros is code-generation (but macros are actually often fine).
But this also only matters for actually reusable generic code. If I'd implement a super-hot-path hashmap in C, I would stamp out a specialized version by hand instead of relying on a generic implementation. But for 90% of cases, a solution like in stb_ds.h is probably good enough.
by flohofwoe
5/26/2026 at 5:58:36 PM
Sure, but now you're actually moving the goal posts. We're talking about the practicalities - you can always achieve the same by doing more work, but it makes a difference that Rust gives you `HashMap` in the standard library that you can just use and get best-in-class performance, every time, with zero work, zero maintenance. The only choice you have to make is which hash function you want to plug into it, and since it is generic, that gets optimized and inlined as well (even with LTO disabled).by simonask
5/26/2026 at 3:57:16 AM
I explicitly acknowledged that:> The only candidate is using virtualization and void* pointers instead of monomorphized generics which some C code does for the lack of better options, but that's not a problem in Rust as well.
But in fact, if speed is a concern to you, even in C you will use "templated" sorting (via macros or code generation).
by afdbcreid
5/26/2026 at 4:22:25 AM
The problem is that the implementation burden with C is so high, that people tend not to do it even in relatively performance constrained situationsby 20k
5/26/2026 at 4:59:36 AM
Neither codegen nor macros (they are a part of the preprocessor) are really a part of C.For the latter, the lack of integration becomes more noticeable if you try writing a macro in which the compare param can accept a function identifier. As the preprocessor doesn't have the knowledge of the contents of the referred function, it can't inline it. In C++ and Rust, their compilers do, so they can.
A codegen tool could overcome this, but you could also make a codegen tool to write Zig/D/C#/Swift in C, or any other language for that matter :). By this point, one could say you are programming in a superset of C, not strict C.
by fluffybucktsnek
5/26/2026 at 6:32:08 AM
> in practice no one really does with C because macros [and codegen] suck too muchby loeg
5/26/2026 at 10:50:18 AM
Rust also has these advantages of courseby nicoburns
5/26/2026 at 12:40:23 PM
Indeed Rust's standard library provides much better sorts both in terms of performance and in terms of resistance to abuse than those provided in the big three C++ implementations.by tialaramex
5/26/2026 at 5:38:57 PM
Right. I'm mostly addressing GP's first question about C and C++.by loeg
5/26/2026 at 7:04:30 PM
It is not uncommon to realize your C program is valid C++ and get a performance improvement just by building with a C++ compiler no other change. The difference is small but C++ has a stronger type system which allows the compiler a few more optimizations. Of course it is possible that resulting program no longer does what you want but actually needing weaker types is rare.Restrict could make things go different but I've never heard someone say otherwise.
Note that we are talking about differences that are tiny here. They can be measured if you are careful but they are almost guaranteed to not be something anyone would notice if they were not measuring
by bluGill
5/26/2026 at 8:43:58 AM
> Is C++ more performant than C? I find this hard to believe.At the compiler level, no. But as you write projects, you will for instance run into things you can do with templates which are infeasible to attempt with macros.
One example might be qsort() - a C compiler _could_ catch cases where it could create an intrinsic qsort based on the data type and function pointer being passed. However, in C++ you have the facilities to create a type safe, genericized sort that will be inlined based on the data structure.
by dwaite
5/26/2026 at 3:59:29 AM
c++ uses rich type system to avoid aliasing when it can, as well as template meta programming.Eg: delete_scene(void *arg) vs delete_scene<T>(T *arg)
by smallstepforman
5/26/2026 at 3:52:44 AM
You can write C style C++ and enjoy the same benefits.In Twitter a user explained me that it is common in embedded space.
You do not need the OOP, RTTI, exceptions.
Like C with most use cases of preprocessor replaced by generic programming.
by fithisux
5/26/2026 at 3:57:48 AM
So? How is that an argument that C++ is more performant than C? It's only an argument that it's not less performant.by afdbcreid
5/27/2026 at 8:31:24 AM
Because you can write C like code, while taking advantage of templates, compile time code execution, and eventually static reflection, that prepare work ahead of time, while at the same time giving more information to optimiser passes.by pjmlp
5/30/2026 at 11:23:56 AM
It is an argument that you can make a faster C-like if you like out of C++by fithisux
5/26/2026 at 8:08:12 PM
>> The caveat is that modern C++ is notably more performant than C and by implication Rust.Please provide proof for this outrageous statement.
by root-parent
5/26/2026 at 8:20:19 PM
I was also dumbfounded by this claim. The only thing I could think of were C++ monomorphic templates that will avoid the penalty of some indirection and DIY dynamic typing.by mynegation
5/27/2026 at 8:14:56 AM
And compile time programming, meaning that you can prepare some algorithms and data structures at compile time, at the expense of executable size.Compile time reflection will make this even easier.
by pjmlp
5/27/2026 at 6:34:20 AM
Is it outrageous because "performant" is kind of a vague term. Does it mean... Fast? GPU-friendly? Scalable? Energy-efficient? Reliable? User-friendly? Maintainable? For what kind of applications?Modern Fortran has a lot to offer for scientific and numeric computation - easier to learn than C++, and easier to optimize in many cases. Scales from small systems to supercomputers, and there is even CUDA Fortran.
by musicale
5/27/2026 at 12:03:13 PM
> GPU-friendly? Scalable? Energy-efficient? Reliable? User-friendly? Maintainable?Nobody uses "performant" to refer to any of those. It usually means either high throughput, or some aggregate of high throughput + low latency + low memory usage.
by Asraelite
5/28/2026 at 4:07:00 AM
Thanks for the response - from my perspective the most meaningful measurement of "performance" (basically "efficiency" but also throughput) is computation per unit of energy (and heat which has to be dissipated), but memory efficiency is also important, as is tail latency in certain cases.What does "Rust is roughly as performant as C" mean, do you think?
by musicale
5/26/2026 at 9:54:23 PM
I think they may be talking about math algorithm heavy code, where C++'s looser almost-just-a-substitution generics system (really "templates" not even quite generics) can be used to create abstractions that compile everything down to inlined maximally performant code.This type of code tends to be hard to maintain though.
AFAIK you can get there in Rust but it's a little more cumbersome. You have to implement a lot of operators, and for that type of code you might actually benefit from #[inline(always)] which is discouraged in normal Rust.
by api
5/27/2026 at 8:22:20 AM
> This type of code tends to be hard to maintain thoughDepends on which C++ version one needs to support, in C++20 and later, it is relatively maintainable with concepts, constexpre, and reflection.
by pjmlp
5/27/2026 at 8:32:11 AM
I think they're all ideas that are relatively obvious intuitive responses to the problem, and yet they may only incrase complexity tbh. For example, constexpr can be used relatively independent of template programming even, yet where they can be used practically before it becomes an unmaintainable mess of boilerplate are the most trivial cases, almost those which you could have hacked in with macros. TBF I think if you need serious metaprogramming, just compile and run a program at compile time.Reflection has always been a mess no matter which implementation or language I've used. Fine for scripting languages, unusable for anything serious complex. The data you need is never there, and the data that is there is unusable, at the wrong semantic level (programming language level not what actually your own domain model semantics).
Also I avoid templates for the same reason, they're quickly becoming unmaintainable. Yes, I've tried to make use of them many times, and I have a fair number of them in deployed software. They work without bugs, of course. But I still don't love them, they're boilerplatey hard to maintain complexity that would be better solved with the right factoring plus a tiny bit of ad-hoc boilerplate. I would like to remove many of my deployed templates if I had the time.
And yes, I even avoid std:: template containers and such. Most uses I regret later. Again, this is for systems programming. They're fine for "scripting", leetcode, business software.
by jstimpfle
5/27/2026 at 8:51:01 AM
Is writing compilers, linkers, database servers, HPC and HFT platforms, OS drivers, networking stacks at IP level, considered systems programming accordign to you, or are they plain business software?by pjmlp
5/27/2026 at 9:06:22 AM
I said, I avoid, I don't love, I was talking about preference. And I'll state: Most of these are written mostly like I say. Please find serious counter-examples.by jstimpfle
5/27/2026 at 9:08:27 AM
A cursory glance to the ones that are publicly available shows otherwise.by pjmlp
5/27/2026 at 9:11:24 AM
You must be talking about Linux, the BSDs, sqlite, postgres, gcc, the mold linker, or let's take some new kids on the block: raddebugger, FilePilot, TaskSlinger?by jstimpfle
5/27/2026 at 9:19:18 AM
I am for example talking about LLVM and GCC, used to compile all those examples.Living in the past? GCC has long adopted C++, last time it compiled with a pure C compiler was back in 2011 thereabouts, not cross-checking the exact year.
A few trees don't make a forest.
by pjmlp
5/27/2026 at 9:21:43 AM
Actually care to open GCC and see what I mean? Check the newest commits and see what they do. Maybe you're living in a dream world where some magic language features do the work for you. Meanwhile people out in the field do actual work by just pushing bytes at the low level.by jstimpfle
5/27/2026 at 9:32:00 AM
To use the developers own words,> Necessary to bootstrap GCC. GCC 5.4 or newer has sufficient support for used C++14 features.
> Versions of GCC prior to 15 allow bootstrapping with an ISO C++11 compiler, versions prior to 10.5 allow bootstrapping with an ISO C++98 compiler, and versions prior to 4.8 allow bootstrapping with an ISO C89 compiler.
> If you need to build an intermediate version of GCC in order to bootstrap current GCC, consider GCC 9.5: it can build the current D compiler, and was also the version that declared C++17 support stable.
https://gcc.gnu.org/install/prerequisites.html
So yeah, if you want to enjoy GCC 4.8...
Now I can bother to show exactly each source file, but Github search is relatively easy to use on the mirror source code.
by pjmlp
5/27/2026 at 11:03:05 AM
Why are you unable to get my point? I understand that GCC doesn't compile with plain C compiler anymore. A lot of my own code doesn't!I'm saying that most of features like templates, constexpr, reflection etc. don't scale well to serious use, as a broad statement. I fully acknowledge this is not a black and white situation. But I encourage you to look at actual pedestrian code, it's mostly not abstracted fluffy magic template code at all. It's pushing individual bytes with totally basic means (mostly C code). Why? Because code using these fluffy features is terribly hard to maintain. Templates lock you in their own language world with incredibly bad syntax and bad ergonomics, in short: it's a pain!
Personally I think even C++ classes (i.e. 1980's C++) are unusable because they bifurcate syntax/semantics needlessly and add implicit invisible scope. But I acknowledge it's somewhat possible to program with classes, and some people like to lean on RAII heavily. I mostly do not like to use RAII, and I've tried many times, I think it sucks for non-toy programming, even though obviously the idea is intuitive.
by jstimpfle
5/27/2026 at 12:38:21 PM
Because I am having this conversation with C folks since comp.lang.c and com.lang.c.moderated days.C++ was perfectly usable already within the constraints of DR/MS-DOS 5.0 powered PC hardware with Borland compilers, instead of plain old C.
Fluffy features power the AI revolution infrastructure.
by pjmlp
5/27/2026 at 4:57:45 PM
Congratulations, empty marketing speech, not reacting to what I say.by jstimpfle
5/26/2026 at 7:44:45 PM
> modern C++ is notably more performant than C and by implication RustI don't think this holds. Rust has the same facilities which C++ has. Rust's metaprogramming capabilities are now on par with C++ (they weren't always). Rust has a similar generics implementation which allows it to do what C++ does in terms of method dispatch and generation. And now Rust has pretty much the same compile time constant generation capabilities that C++ has.
I don't think there's a part of C++ which isn't in Rust at this point. The only thing potentially missing is the experience and investment using those features.
by cogman10
5/26/2026 at 9:40:28 PM
> Rust's metaprogramming capabilities are now on par with C++ (they weren't always).Is that really true, though? I haven't really written any Rust code, so I have no idea, but I don't think Rust has static reflection. Also, aren't const generics much more limited? I've also heard there is no template specialization and no "if constexpr". Or what about dynamic allocations in constexpr functions?
by spacechild1
5/26/2026 at 9:59:09 PM
> I don't think Rust has static reflection.Before C++ in fact through procedural macros. You can do everything you can do with C++ static reflection.
Now, it could be better. Proc macros require you to pull in secondary packages for parsing the token stream. But all the sorts of operations you can do via static reflection you can do via proc macros. That's how the most popular rust serialization package like serde works. It's also how some more popular database libs work like sqlx.
> Also, aren't const generics much more limited? I've also heard there is no template specialization and no "if constexpr".
Both have been added and expanded. AFAIK they are now roughly on par with what C++ const expressions can do. What they can't do, proc macros can do.
> Or what about dynamic allocations in constexpr functions?
IDK if that's possible in rust. Const expr capabilities of rust have been rapidly expanding though in the last year.
by cogman10
5/26/2026 at 10:54:10 PM
> You can do everything you can do with C++ static reflection.Are you really sure about that?
I have a slight problem with such sweeping statements and also with your original claim that "Rust's metaprogramming capabilities are now on par with C++". I think you can only make such claims if you know both languages really, really well.
That being said, I acknowledge that Rust's metaprogramming capabilities have improved significantly in recent years.
> Both have been added and expanded.
In stable Rust?
by spacechild1
5/26/2026 at 11:32:27 PM
It's hard to be concrete without talking about something specific. At the limit, in stable Rust (for 8 years?), a proc_macro consumes and emits an arbitrary token stream at compile time; it's not ergonomic, but it's possible.The equivalent in C++ is in the realm of arbitrary codegen.
by dwattttt
5/27/2026 at 8:33:29 AM
Reflection, Rust community did a very good job driving away the person that cared to do that work, to the point he went back to C and C++ ISO comittees.Several features on C23 were done thanks to his work.
Also compile time execution is much more rich in C++ than Rust, regardling language features and standard library that can be used at compile time.
Naturally none of the languages is standing still, and they will both improve on that regard.
by pjmlp
5/27/2026 at 12:35:51 PM
I agree. Rust could definitely be more ergonomic and IIRC the main reason it wasn't made that way years ago was because the users of proc macros vetoed the new 2.0 API. IIRC over stilly things like it'd make some of their other crates pointless.by cogman10
5/26/2026 at 8:50:12 PM
Last I checked (which was a while ago to be fair), LLVM machine code quality still lagged behind GCC - so things should be slightly more interesting with the GCC back end.There were also some bugs (hence disabled optimization passes) and missed opportunities from the lack of aliasing Rust precipitates - again, not sure where those sit - and GCC will have to play catch up here (unless there are other languages that exercise this part of the backend).
by zamalek
5/26/2026 at 9:11:20 PM
C++ being more performant than C is not something that I've seen in any benchmarks or personal experience.In practice, some of the cases about specialization that was made possible with C++ constructs is also achieved by modern C compilers.
by stephc_int13
5/26/2026 at 10:53:51 AM
Julia is another contender. Julia code can be as performant as C++ code, but Julia code may be even more elegant than C++. Even without accounting for Julia's metaprogramming features, the compile-time expressiveness is top-notch.It shares some of the same drawbacks as C++, though. The language is extremely powerful, so while it is easy to write performant code, it is also easy for non experts to write very suboptimal code.
by nsajko
5/27/2026 at 11:02:03 AM
> Julia code can be as performant as C++ code, but Julia code may be even more elegant than C++But not at the same time
by wolvesechoes
5/27/2026 at 1:19:23 PM
depends on the workload. many are elegant and fast. some require a bit of clunkiness to wring out the last drops of performanceby postflopclarity
5/26/2026 at 12:05:58 PM
Julia is not a systems language. Also its design (GC, dynamic typing) does not allow it to reach exactly the same level as C++.by afdbcreid
5/26/2026 at 6:59:53 PM
you are right one has to be careful to avoid the GC and dynamic dispatch, but if you do it can for sure reach the same level as C++. with tightly optimized Julia code there is little to no overhead over any other low-level language.by postflopclarity
5/26/2026 at 12:33:30 PM
Julia only cares about numerical performance, and in that regime, it’s pretty fast.So not generally fast, no.
by rirze
5/26/2026 at 6:41:01 AM
> The caveat is that modern C++ is notably more performant than C and by implication Rust.This really needs more realworld evidence to back up the claim. In the end the important optimizations happen down in the Clang optimizer passes on the LLVM IR, and those optimizations are the same across C, C++, Rust (or Zig for that matter) - assuming of course that the optimizer can see all function bodies, which in C can be achieved via LTO or alternatively via 'unity builds'.
If the output of one of those languages differs so much (on an LLVM-based compiler) that there are noticeable performance differences I would start investigating whether there's a compile/link setting missing somewhere instead.
by flohofwoe
5/26/2026 at 7:43:39 AM
OP said "C++ can effortlessly do things that require mountains of ugly boilerplate and macros in C or Rust". In theory Rust can be as performant but some things are much less ergonomic to do in Rust macros than in C++ metaprogramming, so often end up not being done.by logicchains
5/26/2026 at 8:25:19 AM
Often that's also because the programmer doesn't know how the optimizer will help them to remove inactive code also in C code. As a simple example, when I have a 'general' bulk-getter function in C which returns a large struct with tons of values but the caller is only interested in one value, the compiler will 'collapse' the entire function call to a single memory access (if it can see the function body, but this is where LTO comes in), e.g.:https://www.godbolt.org/z/n3Y54Yhqr
This is basically the gist of C++ 'zero cost abstraction', but C-style (the bulk of what enables C++ zero-cost-abstraction doesn't happen up in the language, but down in the optimization passes).
by flohofwoe
5/26/2026 at 8:49:24 AM
Nim also has top notch meta programming, probably more so than Zig. You can easily do loop unrolling, specialization, etc. For example Constantine, which is a constant time crypto library that outperforms C, etc.To me programming Rust feels so limiting due to lack of good compile time meta programming with types. That’s the key.
by elcritch
5/26/2026 at 12:01:52 PM
How can you create constant-time code with Nim when none of its backends support it (e.g. LLVM may turn an apparently-constant-time code into non-constant-time assembly)?by afdbcreid
5/26/2026 at 3:31:04 PM
You can see all the details at: https://github.com/mratsim/constantine , but to answer your "how" question briefly here, something Nim shares with most (all?) "systems programming languages" is "easy" integration with assembly languages -- whatever the backend for "most" compiled code is (whatever that "most" even is - weighted by any number of measures of static source size or dynamic instruction counts). Of course, hand-rolled assembly can cost you a lot in portability/effort to port to new platforms/etc.The entire concept of the "performance of a PLang" in terms of the run-time of programs written "mostly in it" is rather seriously under-specified, TBH. This is (or should be) uncontentious in spite of the slew of articles with titles like the one for this thread.
by cb321
5/26/2026 at 3:58:44 PM
Exactly, Constantine generates assembly output and links that into normal Nim objects (e.g. C). That can then used in Nim or in Rust, Go, etc.From its "Why Nim" in the readme:
- Assembly support either inline or a simple {.compile: "myasm.S".} away
- No GC if no GC-ed types are used (automatic memory management is set at the type level and optimized for latency/soft-realtime by default and can be totally deactivated).
- Procedural macros working directly on AST to create generic curve configuration, derive constants write a size-independent inline assembly code generator
by elcritch
5/26/2026 at 8:52:07 PM
I have tried Nim meta programming (to make a tree vaguely like the one used by Zed), and the tooling support of pretty dreadful. I ran into multiple compiler crashes or simply unhelpful and confusing error messages, alongside LSP hangs.by zamalek
5/26/2026 at 9:41:56 AM
I'm surprised to see someone putting forth the argument that templates are easier to use than macros. I've found the opposite and in many cases the monomorphization of templates to explode code size which has a fairly material impact on performance in my domains. Debugging macros with cargo expand is infinitely easier than debugging template errors.While you can write high performance C++ my experience is that many people will reach for shared_ptr and their like while Rust will force them into proper structure/ownership as Arc and their like have a lot higher friction.
by vvanders
5/26/2026 at 11:04:30 AM
You say you are "summarizing" something but instead you seem to have just injected your opinion that C++ is "notably more performant than C and by implication Rust".It's true that you can express many things in C++ -- the problem is that the language deliberately doesn't distinguish whether the things you've expressed are nonsense, so you might well have written total nonsense and you only find out when, much later, diagnosing a real world event you discover oh, this is nonsense, why did this even compile? Well sorry, it was "more performant" to allow nonsense.
by tialaramex
5/28/2026 at 9:20:26 AM
[dead]by jccx70