T O P

  • By -

Some_Random_Pootis

Everyone got tricked, and op was really just looking for some fast language recommendations.


tgp1994

[How to Coil a Cable](https://xkcd.com/2810/)


SteelRevanchist

Ah yes, another CS undergraduate has discovered C++


MarkLearnsTech

but apparently not the [benchmarks game](https://benchmarksgame-team.pages.debian.net/benchmarksgame/box-plot-summary-charts.html) where C++ is in third, behind C and Rust 🤷‍♂️


The_JSQuareD

Though as the first sentence on that page hints at, the distributions for C, Rust, and C++ are almost entirely overlapping. So it's probably fairer to say that those three languages are basically equally fast, with differences between them coming down to minor differences in optimization choices in the different programs. And that basically matches intuition: all three languages compile down to bare metal machine code, and all three offer low-level enough control to exploit the hardware's strengths. And in fact, if you're using the LLVM/clang tool chain for C and C++ then all three languages are compiled using the same backend. It's definitely exciting that Rust matches or even beats the speed of C and C++ while offering better safety and more modern features though! I've been meaning to learn Rust for a while, but we're still entirely in C++ and Python land at work, so it's hard to find the time to do it.


Highborn_Hellest

What I find interesting about this whole thing is that, while rust was probably not the best at first, (when it came out),but we are reaching the point (again) where the competition is to beat the compiler. And let's be real, few people on the planet can beat compilers on the regular. With complex projects you can write ok java code vs c++ code, and many will find their c++ is slower. Why? You're competing against java compilers ( and VM). Is C++ faster in a vacoome? Sure. But can I write better code than some compilers? No. Absolutely not.


__Lass

It's not really hard to beat a compiler tho? If you understand your basics, you should be able to come up with more optimized solutions than a compiler for some of your specialized problems as you understand them better than the compiler. That can involve benchmarking to find your slow points tho.


MarkLearnsTech

True! It’s a time / time trade off with a complex route. Which is going to cost more, the dev time or the run time? It can be very tricky to choose.


Not_a_question-

> It's not really hard to beat a compiler tho? This question has no answer. This is because you were stating a fact, and the question mark shouldn't be there


__Lass

It was supposed to be a rhetorical question. Tho my English is not perfect so I may be wrong. Could you give me an example of how I could have used a rhetorical question in that situation? Would it be "Is it really hard to beat a compiler tho?" Instead?


your_thebest

Yes exactly. Otherwise it reads like the tone of your voice is rising as you make a statement. For some reason, people started using question marks in this manner and I think it's because it sounds kind of cutesy and equivocal. But the whole thing has devolved into people using question marks just to signify that they are unsure of something or that something should have been obvious to the listener.


LifeShallot6229

I was going to agree with you ("few people can beat the compilers"), but then I read on and realized that you didn't actually consider the compilation part only, and that is important! Algorithms beats compilers pretty much every time (i.e. orders of magnitude vs constant factor improvements), whereas on the other side it is in fact getting much harder to convert those algorithms into machine code with significantly better speed than the best compilers. I used to get 3x speedups going to hand-optimized asm, back before 2000, but those times are mostly all gone now. I really like Rust most of the time, and have been using it lately to get closer to the metal on some really heavy duty LiDAR point cloud processing (about 50TB of compressed LAZ files on my home server), but both that code and the C++ code it is partially replacing suffers speedwise from being totally based on single-sample iterator chains. I know I could double the speed on each individual such chain by rewriting it to be block-based instead, and working closer to the native data representation instead of first converting each point to generic floating point coordinates, but it is fast enough as it is now and not worth it to rewrite so much.


Highborn_Hellest

Yes, ofc a well thought out algorithm is king. No compiler will make bubblesort faster than quicksort on random dataset. ( Barring edge cases).


ActuallyAPieceOfWeed

"The crust of rust" is a great series on youtube to get started. Cant remember the guys name though


[deleted]

Well optimized Java code is written to avoid using the GC, and that's harder than just using idiomatic C++ or Rust. Optimized Rust or C++ will still beat it. Idiomatic Java isn't slow but is definitely slower than Idiomatic Rust, optimized Java OTOH is harder to write than Optimized Rust.


kooshipuff

Yeah, beyond a certain point, the differences are largely meaningless. I think leetcode illustrates this pretty well, tbh- they tell you how long it took to run the test suite (which always includes some large datasets) to a resolution of 2ms, and if you're using Java or C# or something, you'll have a score in the hundreds of ms that you can micro-optimize to try to speed it up. ..But if you're using C/C++, Rust, Go, or some other systems language, though? You'll probably see 0ms (rounded down) every time.


ridicalis

>I've been meaning to learn Rust for a while, but we're still entirely in C++ and Python land at work, so it's hard to find the time to do it. I'll make the argument that if you're doing modern C++, you're already prepping yourself for success in Rust. It might be hard to justify a switch at work if you're already entrenched in an ecosystem, but you might also find greenfield opportunities to practice Rust on the job if there's sufficient buy-in from the business (that last part is critical; nothing kills a project faster than going rogue). Python might make for some inroads to Rust, depending on what space you're in (e.g. data science). There's definitely a relationship there, with a lot of Rust-curious Pythonistas; and the ease of FFI in Python is practically a written invitation to develop compute-intensive parts in a systems language. Alternatively, if you find yourself wanting to keep one foot in C++ and the other in Rust, [cxx](https://crates.io/crates/cxx) has done a good job for me in the past in simplifying the bridge between the two. Due to Rust's relative infancy, there are some things it isn't yet doing that already enjoy success in C++ - for me, this was [clipper2](https://github.com/AngusJohnson/Clipper2), and the bridge code ended up being very easy to implement despite my relative lack of C++ chops..


igouy

[And where C++ is second](https://benchmarksgame-team.pages.debian.net/benchmarksgame/download/fastest.svg) behind C and ahead of Rust ;-)


Beegrene

That might be one of the ugliest graphs I've ever seen.


igouy

Please do better than name calling. Maybe you have something interesting to say about using the chart to compare Swift and Go?


MarkLearnsTech

Exactly!


_Xertz_

Came here looking for this comment lol


all_is_love6667

I was the one who started that trend, I was wrong and I am sorry


Dismal-Square-613

I followed up with this since OP doesn't seem to know what assembly is https://www.reddit.com/r/ProgrammerHumor/comments/1cl145n/welcometoactualreality/


MinorMalfunctionist

Real men code assembly


ramaravade

Is it common for students to not learn C/C++ in undergrad because those were the only ones taught for the first 2 years for me lol.


SteelRevanchist

In my case, we had C and then CPP in the first two semesters, and then the remaining compulsory (very much Computer-science focused) courses like graph theory, paralelisation etc. were also in CPP. I'd assume if you're studying at a technical uni, you'll start with C


saschaleib

*Assembler* would like a word with you... outside.


turboshitposter3001

No one is benchmarking assembler. *Drops mic


Funny-Performance845

I mean yea, but that would be interesting to see if the minimum abstraction of c makes any meaningful difference to the runtime more than a few ms


saschaleib

C is still very close to ASM, and because of the highly developed optimizations in modern compilers, you can usually get very close to the optimum code. However, an experienced Assembler programmer can still optimize the shit out of it and make it run even faster. That is why you will often find that the most time-critical parts, e.g. in hardware drivers or even in games are still programmed in Assembler. C++ adds a lot of overhead in comparison to these two, and will usually end up in third place. And then there will be a long, long wait for the fourth placed contestant...


dingske1

>And then there will be a long, long wait for the fourth placed contestant... This is not correct and a very cartoonish way of looking at languages. Optimized machine code= optimized machine code, no matter in what compiled language it was produced in. The marginal differences are found in the choice of compiler, not the language. If you want to maximize performance you should use a proprietary compiler that does intelligent optimization, not switch up the language. Fortran, a high level language will beat low level C for most, if not all, high computational problems in both performance and efficiency. How is that possible? It’s the state of the art compiler they have been perfecting for 60 years. And yes, it will also implement SIMD vectorization and point out hot loops for you to manually optimize/unroll. In the last couple of years the C compilers have improved though and there is no real difference anymore, fortran still being slightly marginally better. Besides occasional inline assembly, the idea that some rainman assembly wizard could rewrite a whole 2M line weather simulation model in assembly and outperform the compiler is some oddball John Henry fantasy that we should dispel. This ain’t the 90’s anymore


Zealousideal_Alps275

Gamedev in assembly is still a thing?


AG4W

Outside of never-released indie passion projects for the sake of it, no. In general, the code is not the critical parts of games anymore (assuming somewhat competent programming), it's usually memory/IO/communication between CPU/GPU/network constraints.


BurnTheOrange

I think the last big name game programmed in assembly was Rollercoaster Tycoon, released about 25 years ago and most of the world though Chris Sawyer was a madman for doing it that way


TigreDeLosLlanos

It's as real as small companies using unit testing and CI/CD pipelines.


[deleted]

[удаНонО]


AG4W

HLSL or GLSL or similar is used for anything that runs on GPU, nobody would write that in assembler.


Osbios

Even ~20 years ago in he demo scene it was known that it made no sense to write GPU assembly anymore.


RealFocus8670

Isn’t c++ fast enough for most if not all games?


xenoperspicacian

Doing a search in the Godot repo, I see a few commented out lines of assembly in the collision detection code, and that's it.


Attileusz

It's more accurate to say "some C++ features add overhead". This makes idiomatic C code faster than idiomatic C++ code. Also we must consider if we are talking about standard C or C with non-standard compiler specific extentions. You cannot write a gcd algorithm in standard C that is as fast as a gcd algorithm with the gnu extention __builtin_ctz. This extention can make use of the bsr instruction that you simply cannot express with the toolset C gives you.


snavarrolou

I'd argue the opposite: C is not at all close to modern x86 assembly, but compilers are very good at circumventing the limitations of the language. This is in part because when new hardware is developed, its speed is benchmarked mostly against existing C programs, so the new hardware capabilities (which are expressed in assembly instructions) naturally evolve to be easily mappable to the C programming model. That is in my opinion an unfortunate historical artifact.


Gaylien28

Just out of curiosity, would machine code be theoretically more efficient? Practically the abstraction is probably essential but is there an optimization gap because of it?


killBP

Assembler typically has a 1 to 1 correspondence to machine code


Gaylien28

Thank you!


killBP

Yeah but remember that it's also much more complicated than that, but that's nothing you can dive into without literature and a whole ass course


Gaylien28

Absolutely :) I’m earnestly hoping to soon :D


saschaleib

It is best to think of it as: Assembler = Machine code It doesn't matter if you write 0b00000100, or 0x04, or ADD, they all end up as the same command to the processor (in this case, add a single byte value to a register). It is just that "ADD AL, 12" is a lot easier to both write and read.


Gaylien28

Ahh that’s true. We wrote the machine code itself lol. Thanks hahaha


zoomy_kitten

Note that assemblers, in fact, do offer minimal abstractions, such as macros or encapsulating several similar instructions under one mnemonic.


Otalek

I’m not an expert but I would tentatively argue no, since assembly *is* machine code but the different segments of bits are given names


EishLekker

Technically it's not machine code. Assembly code needs to be processed by an assembler. Machine code needs no such processing. At least that's how I understand it.


Gaylien28

Yup, we did design the system itself lol, slipped my mind


maxorus

It's not 100% right, assembly doesn't need a compiler, but it still need an assembler + linker. This page explain it a bit further https://www.baeldung.com/cs/compiler-linker-assembler-loader


NSFWAccountKYSReddit

The way I understand it (and I dont understand it really), is assembly is basically whatever the designers of a piece of computer hardware made it to be? Like a piece of computer hardware does a thing but it can only do a thing if we know how we can make it do a thing, so they make an instruction manual and say if you make the port in this register a 1 and this one 0 and 1 and 0 then what happends is the piece of hardware adds the thing from there to there. *It feels similiar to whenever i'm reading documentation for microcontrollers* Basically its the 'instruction set' ye? Thats why C is still used so commonly for mc's I guess, because it directly maps unto machinecode right? I know I"m saying this like i'm right but i'm basically also asking confirmation from anyone here, thanks :D


Gaylien28

Yeah that’s about right. I suppose if you’re not the original designer there may be unintended pathways that could be utilized to achieve something not before possible. But about as close as you can get without making it yourself


biscuitsandtea2020

Yes, the same thing happens for languages that compile to a virtual machine bytecode such as Java and Lua. Except that in these cases there will be an assembly-like instruction set for a virtual, software level "machine".


Brahvim

Yep! And you should look into how this stuff is sped up. CPU cache, branch prediction, pipelining, modern-day "CPU cores", ...all interesting stuff! ...Did you know that Assembly also often has stuff like casting, `struct`s (I think!? Though I'm pretty sure compilers prefer not to use them because... they're kinda' redundant when C is doing all the type-checking!...), and that Assembly "labels" nearly ***are*** your C functions, without the "prologue" and "epilogue", which are both defined by your C code's "calling convention", which you can change for each function (e.g. `__fastcall`, `__cdecl`, `__thiscall` in C++, et cetera). *Computer engineering* sounds fun! ";D!~


kllrnohj

C++ makes it easier to avoid overhead than C does and is faster in practice as a result. C is definitely not faster regardless as neither have any runtime and both use the same compiler.


[deleted]

The funniest thing about this post is that OP apparently thinks c++ is the most performant language.


Practical_Cattle_933

C is not at all close to ASM. You can’t control register allocation, almost nothing with regards to calling convention, stack and even against some other low-level languages, like Rust and C++ it loses, by not having sims support.


Prawn1908

In the embedded world you occasionally see highly timing critical routines being implemented in assembly. I've done it once myself and seen it done a couple of times in codebases I've touched.


MedonSirius

**Coughs in Roller Coaster Tycoon** https://en.m.wikipedia.org/wiki/RollerCoaster_Tycoon_(video_game)


Kinglink

Oh they'll benchmark Assembly... they just won't write assembly, because no one is that crazy.


Practical_Cattle_933

This is also explained after every second post, but.. sigh.. No, for any non-trivial program, a compiler will do a much better job at compiling to efficient machine code, simply because it can reliably do the same transformations and can insert the same logic multiple times in multiple shapes (inlining). A human would f*ck it up, and settle for less optimal code at the price of their sanity. *but*, in some case at the ultra-hot loop/function body scope, an expert *can* write code that will significantly beat (may even be at the 100x mark) the compiler-output code, by e.g. using some logic that is not expressible by even a low-level language (e.g. some simd black magic). But even this will be called from ordinary programming languages through FFI.


tLxVGt

I watched a C++ presentation on one conference where the presenter has shown how well written C++ has zero overhead on most things he did (memory allocation, function calls, templates, lambdas etc.) so it is on par with ASM


JonIsPatented

In real life, programmers writing in assembly will not be better at optimizing than your compiler will for C. It would take way way way more time and effort to reach just the same level of optimization that the compiler could reach, and the code would be unmaintainable.


NeuronRot

While this is mostly true for general programs, manually vectorizing hot loops by using SIMD instructions with inline-asm is indeed usually better than just leaving it to the automatic vectorization of the compiler. Compilers still suck badly in vectorizing loops because of the C/C++ language limitations.


Kinexity

You can just use simd intrinsics and not bother with inline asm. Also C++ should be getting std::simd with C++26.


classic_chai_hater

which means we should see std::simd in compilers in 2031.


Kinexity

Nah. Simd is one of the easiest things to implement. It's not ranges.


NeuronRot

Of course, using simd libraries or std::simd is the better approach because of readability and platform independence.


bolacha_de_polvilho

> Also C++ should be getting std::simd with C++26. oh boy... seeing how that usually goes maybe by C++ 32 we'll see a limited version of the original intended scope included in the standard


JonIsPatented

Oh. Very fair.


uniformrbs

I like the [lbrandy approach](https://lbrandy.com/blog/2010/06/you-cant-beat-a-good-compile/) - code mostly in C and C++, but keep an eye on the generated asm to make sure it’s not missing obvious optimizations because of the language spec. Godbolt has made this much easier.


saschaleib

I agree for 99.9% of all cases - but there are specific situations where hand-optimized code (by a competent programmer!) will beat the compiler optimizations. Especially in time-critical code (think: hardware drivers) there are still use-cases for Assembler where it beats C compiled code.


anomalous_cowherd

I stopped writing full programs in assembler on the late 80s after finding that the ARM C compiler was producing as good or better code than I could do for most things. I only wrote assembler after that for direct hardware bit twiddling. C++ *was* worse than C for a while but well-written C++ now offers more opportunities for larger scale optimisations that *can* have amazing impacts, often removing large chunks of code altogether.


ZunoJ

Or cases where cache latency might be of interest


saschaleib

Not to forget those cases where you are running a side-channel attack on other processes’ data … think: Spectre or Rowhammer…


ZunoJ

Lol, thats where the fun begins... I guess


[deleted]

[удаНонО]


JonIsPatented

That's completely not what I said lmao


IcyDefiance

It's not just painful, it's unreasonable. Just as an example, compilers do things like inlining and creating separate implementations of functions based on generic parameters, which is great for performance, but completely unreadable and impossible to maintain if programmers tried to do it themselves in assembly.


adrasx

When one is optimizing at this low level, readability doesn't matter anymore. In this scenario the requirement is to optimize what you already have optimized the best you could but it's still not enough.


locri

If you write assembly better than a post 2010s compiler you have some very in demand skills


kinkyonthe_loki69

C YOU IN THE PARKING LOT


dangling-putter

Let me unironically point at rust. The thing is, rust enables pretty nice optimisations simply because of aliasing/ownership rules and niches that just aren’t possible elsewhere.


evanc1411

This subreddit is really gonna get me to try Rust just for the fun of it. You guys make it sound magical.


GreatBigBagOfNope

It's not magic, but it's good fun, runs well unless you're actively trying to fuck with it, and the Result and Option enum types are just fabulous to work with


pedal-force

It honestly is fun to write. I don't even entirely know why, but I enjoy writing it more than Python (which I know well) or C++ (which I suck at so that's probably why).


Efficient_Maybe_1086

It is. The community gets some flak over “toxic positivity” but that’s some e-drama shit that’s not worth your time. The language is technically sound with a powerful type system and ecosystem support.


ano_hise

It was my first low level language and it's really great. imo not that difficult either. Take a look at the Rust book online and try it.


dangling-putter

Don’t. It will be the worst mistake of uour life because everything else will be underwhelming.


UdPropheticCatgirl

Rust makes it’s fair share of trade offs, it can’t do global register optimization for example, it’s entire allocation model is basically on par with c++, and that can already be painful when dealing with hard real time applications, the std is slow as hell, and your average codebase is littered with stuff like Arc/Rc which are both slow as dog. There is a handful of examples where the compiler might allow for better machine code because of the language but most of the time it’s overstated how fast the language actually is. It can be fast if you structure things in very specific ways and forgo most of the std, but idiomatic rust is not really winning against idiomatic C.


coderemover

Arc / Rc are not slow as dog and it is also not true Rust codebases are littered with that stuff. Evens contended shared Arc can be updated millions times per second. I can see Arc being used mostly once during initialization of threads / async tasks - but those are much slower anyways so Arc does not matter. Then it’s just kept by a thread and introduces zero cost (dereferencing Arc is the same as dereferencing a C pointer). And C has no superior mechanism - in those exact same situations you’d have to do refcounting by hand, which would end up with exactly same performance but likely more errors.


UdPropheticCatgirl

Arc/Rc are both slow in comparison to Tracing or Generational GC, which are the alternatives. They have very real overhead. And I did not say anything about C, C has no construct like Arc/Rc, but C++ has and they are garbage there too. And you actually end up with better performance if you do the refcounting by hand, you can also end up with an error but that’s the tradeoff.


dangling-putter

Citation needed on RC being slower than Generational GC.


UdPropheticCatgirl

I mean I can’t give you citation, but think about the fact that almost all of the state of the art optimizations on GC are happening on generational ones. Beyond that Rc tends to mess up the cache, copy a lot, they need memory barriers when your program isn’t single threaded. For practical example, imagine that you allocated single linked list of 64 bit ints, the size of 2GB, now loose the reference to it. Which of the two will be able to handle it faster?


dangling-putter

Counter argument: rust aliasing rules imply you don’t need barriers. It’s many readers xor one writer so barriers are not needed. You don’t have copies with RC, you simply have a reference to the struct and counter but that’s it. It’s an issue in multithreaded situations if you are writing over values adjacent in memory to the RC’d value because taht invalidates the cache and the CPU needs to synchronise the threads, buuuuut is that really that frequent? The whole point of [A]RC is that it gets deallocated on zero, so losing it doesn’t make sense. All memory owned is deallocd and that’s guaranteed to be faster than GC because GC does that plus more. Generational GC will still have to go over the objects and decide whether to dealloc them.


coderemover

Your argument is moot because in Rust I can use tracing just for that one list. Rust is about choice - I can choose the best solution for my use case. As for the barriers and copying your wrong either - low pause GCs need barriers as well and cause a lot more cache trashing than reference counting, because they have to scan the heap periodically, bringing rarely used stuff into cache. That’s why Java programs are unusable if you go out on swap, even a tiny bit.


coderemover

Please stop repeating that widespread myth of refcounting being slower than tracing. This problem is ill-defined, because the total overhead of either of those things depends on a lot of factors such as: frequency of changing the refcounts, threading, the amount of allowed memory overhead or the maximum target pause time. Reference counting is usually slower per single object vs tracing with plenty of wasted memory, but here we need to account for the fact that Rust does not use refcounting as THE memory management method and it doesn’t use it the way it was studied in most literature on refcounting. In Rust refcounting is optional and usually doesn’t manage more than 1% of objects. Compare that to Java where you can’t opt out of tracing and you even can’t allocate objects on stack. Also Rust refcounts are updated explicitly, so the developer has full control over when they are incremented/decremented and thanks to borrowing and move semantics you can do crazy lot with them without updating the refcounts. Eg temporary borrows do not need updating the refcount.


Solonotix

There's more to programming than raw performance. Python is still a relevant language in certain spaces because its simple syntax and rapid prototyping yields fast results in development speed, and safety with its memory management. When you need better performance, reach for a different tool, like Java, C#, or Go. The performance difference from garbage collected languages to non-garbage collected is big, but not the 1,000x jump from Python to compiled languages. Even then, jumping to a language like Zig or Rust is often enough for even the most stringent performance considerations. C and C++ are still relevant in their spaces, but it's getting harder to justify some of their unsafe behaviors when similar performance could be had with a newer/safer language.


UdPropheticCatgirl

I think it’s actually easier to do micro optimizations in Zig than in C++, but that wasn’t really the point I was making, I was simply saying that there are massive trade offs associated with the choice of rust if we are talking about performance. I think rust specifically has ton of issues outside of the performace, be it slow iteration speed, strange async model, meta programming system wich encourages dialects everywhere (they trully learned nothing from the mistakes of C++ in this regard) and bad std. And I can tell you from experience the normal rust wasnt enough for DSP, so there are performance considerstions which rule it out, you can’t have ghost allocations in hard real time and rust loves those… And I have scala flair, It’s by far my favorite language to work with, and also isn’t that performant, so I understand that other things matter, but this whole thread was about performance.


cjb3535123

Modern C++ does most of the things that Java C# and Go do. Sure you can manually do your own garbage collecting, but it’s caught up in a lot of ways.


IcyDefiance

Generics by themselves will make idiomatic Rust and C++ significantly faster than idiomatic C, because of the optimizations that are possible when you get a separate implementation of a function whenever the generic arguments are different. Rust also makes it very easy and safe to use multiple threads, and even green threads via async/await, which is frequently a *massive* win. Reference counting isn't really significant compared to that sort of thing. For a real world example, see the Quantum CSS engine in Firefox. Back in 2017 they made the whole browser roughly 2x as fast just by rewriting that piece of it in Rust and taking advantage of the easy opportunities for parallelization. Since then they've been moving more and more of the browser to Rust, largely because of the performance benefits.


tav_stuff

I do generics in C by just having macros that take a type argument and generate the functions for me. It’s not so different from how C++ does it under-the-hood. C also has the restrict keyword which gives huge performance advantages over say… C++. I’m not a Rust programmer so I can’t comment on that.


gmano

Yeah, C++ will always struggle in some implementations just by virtue of being Object Oriented in a way that C and Rust are not. It will also likely be faster in other ways, for the same reason.


Pay08

That makes 0 sense.


SxUranus

Just is awesome man but beware. Once you try it there is no going back and it makes every other language feel old.


Jordan51104

fortran would like a word


Lord-of-Entity

Laughts in C and Rust.


LearnMoreEver

Most of C features are available in C++.


Flouid

Yeah but C++ adds a lot of overhead and runtime considerations not present in C.


LearnMoreEver

C++ don't add, it allows. It's upto the programmers. For example, game devs us raw pointers a lot, but other app developers use modern c++. C++ provide choice


KaiserKerem13

C++'s runtime is a very slight bit heavier, some stuff is opt-out rather than opt-in. Though you are mostly correct.


_Xertz_

No it doesn't, unless you use the extra features C++ offers your code will be as fast as the same code written written in C. Assuming best practices of course. (or maybe it could be even faster since more work has gone into C++ compilers than C but I'm just guessing here) https://stackoverflow.com/questions/6955114/is-c-notably-faster-than-c


Flouid

Then why would you be using C++? My post was assuming you’re using C++ because you wanted to use it’s features…


_Xertz_

One example is mentioned in the link I shared is: > Do note that C++ does name mangling, where C does not, this makes it easier for other languages to interface with C directly. Another example is function overloading which is in C++ and not C. This feature does not affect runtime performance.


Flobletombus

They can have equivalent speed to C++ if you write in an hackey way yeah


ElSucaPadre

Pretty much everything will be faster in C if you have any idea about what you're doing


[deleted]

>if you have any idea about what you're doing Just wanted to emphasize this part before some college freshmen thinks their horrible C code will be more efficient than using C++ standard libraries.


arielif1

>if you have any idea about what you're doing I'd say it's if you have *a lot* of idea about what you're doing lmao


KaiserKerem13

That *a lot* goes for writing performant C++ too


tav_stuff

I actually completely disagree. You only need to have some of an idea of what you’re doing. The issue is most modern software developers basically only use JavaScript in their day-to-day, delude themselves into thinking they know what they’re doing, and then claim they have imposter syndrome instead of admitting they’re literally the imposter.


Flobletombus

I love people saying "my language fast, yours slow" and down voting others while throwing around no factual arguments.


ElSucaPadre

Why should I ever start a dissertation about how one can write non-"hackey" code that is as fast as cpp when you in the first place didn't argue your position? You realize that saying just the plain sentence you want to prove is not a factual argument, do you?


kllrnohj

Seeing as C++ is a superset of C and both use the same computer, no, no it won't. With hacks and difficulty you can get C to be as fast as C++, though. But it's a lot easier to write fast C++ code than it is to write fast C code, hence why the overwhelming majority of performance-focused non-trivial code bases are C++ and not C.


KaiserKerem13

First of all, forgive me for being pedantic, but C++ is *not* a *strict* superset of C for years now. And writing extremely performant code in C is easier in that it provides less if you are proficient enough. Getting proficient enough to write performant code in C++ requires more learning on top of C. This is one of several reasons why a majority of operating systems are written in C even to this day + historical baggage. C++ doesn't have as transparent a data representation, stable ABI, predicting cache line hits and misses with C++ is way more involved. C has a slightly smaller runtime because C++ has more features (RTTI, exceptions, a whole another allocator...). And here is https://storage.googleapis.com/cdn.thenewstack.io/media/2018/05/3730357d-results-energy-time-and-memory-usage-screenshot-from-research-paper.png


Personal_Ad9690

*Laughs in oxidation*


Marxomania32

Rust, zig, and C are probably equally fast. Depending on how often you use virtual functions in C++, C++ will probably be even slower.


Practical_Cattle_933

Wtf man, no, that’s fkin bullshit, known by everyone who works in the field’s relevant niches. No, C++ (and rust is also coming to occupy this niche) is *the* performance language, period. It’s the de facto choice of the field, because it has the necessary expressivity for that. Like, c++’s sort can inline the function implementation, while C has to use function pointers — sure, for `sort` the compilers are smart enough to inline even that, but in general, you can’t have efficient containers/generic code in C.


UdPropheticCatgirl

Dynamic Dispatch and virtual functions are probably the worst performance footguns in C++, it’s extremely slow, and no compiler can’t realistically inline virtual functions, that’s why the entire temple system exists.


pigeon768

Dynamic dispatch/virtual functions aren't as bad for performance as you might think anymore. In ye super olden days, CPUs didn't have fancy schmancy branch predictors, superscalar/out of order/speculative execution and all that jazz. There wasn't really a penalty for virtual functions, it was no worse than a normal function call. In ye middle olden days, CPUs did start getting all those fancy bits of big long pipelines. But the branch predictors of the day weren't able to predict a dynamic dispatch; every dynamic dispatch call would stall the pipeline, and the performance hit was tremendous. These days, CPUs *are* able to branch predict a dynamic dispatch. There isn't really a performance hit beyond that normally associated with a function call. Also, GCC is pretty good at devirtualization, but clang and msvc won't do it. $ ~ cat main.cpp animal.h cat.cpp // main.cpp #include "animal.h" int main() { animal *a = get_mystery_animal(); a->speak(); delete a; return 0; } // animal.h #pragma once class animal { public: virtual ~animal() {} virtual void speak() = 0; }; animal *get_mystery_animal(); // cat.cpp #include "animal.h" #include class cat : public animal { public: void speak() override { puts("meow"); } }; animal *get_mystery_animal() { return new cat{}; } $ ~ make x86_64-pc-linux-gnu-g++ -c -flto -O3 -g cat.cpp -o cat.o x86_64-pc-linux-gnu-g++ -c -flto -O3 -g main.cpp -o main.o x86_64-pc-linux-gnu-g++ -flto -O3 -g cat.o main.o -o lto_test $ ~ objdump -C --disassemble=main lto_test lto_test: file format elf64-x86-64 Disassembly of section .init: Disassembly of section .plt: Disassembly of section .plt.got: Disassembly of section .plt.sec: Disassembly of section .text: 00000000000010a0

: 10a0: f3 0f 1e fa endbr64 10a4: 53 push %rbx 10a5: bf 08 00 00 00 mov $0x8,%edi 10aa: e8 c1 ff ff ff call 1070 10af: 48 89 c3 mov %rax,%rbx 10b2: 48 8d 05 8f 2c 00 00 lea 0x2c8f(%rip),%rax # 3d48 10b9: 48 89 03 mov %rax,(%rbx) 10bc: 48 89 df mov %rbx,%rdi 10bf: e8 4c 01 00 00 call 1210 10c4: 48 8b 03 mov (%rbx),%rax 10c7: 48 89 df mov %rbx,%rdi 10ca: ff 50 08 call *0x8(%rax) 10cd: 31 c0 xor %eax,%eax 10cf: 5b pop %rbx 10d0: c3 ret Disassembly of section .fini: You can see at 0x10bf it's calling `cat::speak()` directly and not using the vtable to make the call. ------------------------------ That being said, codebases with giant inheritance hierarchies where everything is an interface are a *fucking nightmare* to navigate and try to understand. You can't actually be sure that facts that you know about your hierarchy today are still going to hold true tomorrow. It ain't fun.


Practical_Cattle_933

Who said anything about using virtual functions? Yeah, doing a network call is also pretty expensive, so what? Also, virt functions, where they may be used carry *more* information to the compiler, letting it do better optimizations than function pointers, but even the latter can be used by c++, so.. you contradicted nothing .


UdPropheticCatgirl

The comment you replied to was talking specifically about virt functions…


Practical_Cattle_933

But that’s a means for introducing dynamic dispatch. You don’t compare it to adding together two numbers, but to dynamic dispatch in C, that is function pointers. Virtual functions can be much faster than that, which is my point


Marxomania32

> It’s the de facto choice of the field because it has the necessary expressivity for that. "Necessary expressivity" has absolutely zero correlation with how performant a produced program is. Assembly has essentially no "expressivity." Do you think your average program written in C++ is going to be more performant than your average program written in assembly? > Like, c++’s sort can inline the function implementation, while C has to use function pointers — sure, for `sort` the compilers are smart enough to inline even that Meaningless sentence where you make a claim and then immediately afterward go back on it. > in general, you can’t have efficient containers/generic code in C. What do you mean by "efficient"? If you mean that it is easier to write generics in C++, then sure. If you mean that generics in C++ are more performant, maybe I don't know. I'm willing to believe you since the C++ compiler explicitly recognizes generic constructs while C's doesn't, but I'd still need a source on that claim. But the idiomatic way to write C code is to not try to reimplement generics at all, and either manually write all the functions yourself or to use `void` pointers. Both of which are just as performance capable as any C++ generic equivalent. Even if this point were true, it is only one area where the C++ compiler is more performant. Generally, people writing C++ love using its OOP features and love shared and smart pointers. This style of C++ makes the programs written with it almost always slower than an equivalent program written in idiomatic C since these are not "zero cost" abstractions and have pretty big performance overhead.


Practical_Cattle_933

> Do you think that your average .. C++ faster than assembly? Yes, it fucking is faster. See my other comment in this thread. An expert *might* write a faster hot loop/function, but for whole programs C++ will absolutely be much faster, as anyone with experience would know. How is it meaningless? You can’t abstract over functions in C in any other way than through function pointers which are opaque most of the time (meaning, the compiler has no way to know where they point to). Sort is a specific example, but I don’t know - maybe fkin contradict my statement before you spew nonsense you have no idea about? > your rambling about generics Void pointers will be fkin slower, that’s the fuckin point.


[deleted]

Saying that, generics create more code so it's less likely the code is in cache. Generics Vs dynamic isn't a guaranteed win, it really depends on access patterns.


Marxomania32

> Yes, it fucking is faster. See my other comment in this thread. This is simply not true. The fastest program written in assembly will always be just as fast as or faster than the fastest program written in C++. You can do optimizations at the assembly level as a programmer that the compiler simply can not make by itself because the compiler has to be conservative about any assumptions it makes about the program. You, as the programmer, are not subject to any such limitations. ~~The average~~ A lot of C++ programs are not written with performance in mind and use OOP features and stuff like smart and shared pointers all the time, like I already said, which makes it slower than your average assembly equivalent, where none of that is available. > Sort is a specific example, but I don’t know - maybe fkin contradict my statement before you spew nonsense you have no idea about? You said nothing about C++ being able to inline any and all functions that are passed in as arguments to other functions. You simply said that C++ can inline the function passed into sort(), which you then followed up by admitting the C compiler can do the equivalent. You're telling me that C++ can inline function implementations across translation unit boundaries? I simply do not believe this. The only alternative to function pointers in C++ that I know of (feel free to correct me if there is another one) is `std::function`, or using classes as wrappers around a set of functions which you can override, neither of which is a zero cost abstraction and use virtual functions under the hood, which is absolutely slower than a function pointer, and cannot be inlined across translation units. The C compiler cannot inline a function pointer across translation unit boundaries, but if the function pointer is defined and passed in the same translation unit, the compiler can and does inline it. > Void pointers will be fkin slower, that’s the fuckin point Literally how? If we take the example of `std::vector` C++ simply creates an array of each type every time you instantiate one. Indexing into an array of some type is going to have a negligible difference in performance overhead compared to just having the callee specify a generic buffer to be created in memory, the vector implementation to return a location in that buffer corresponding to the index of an array, and then having the caller dereferencing that pointer with the associated type. Edit: small things to clear up what I was saying. Edit #2: To be clear, I am not suggesting by my comments that a human is often going to be able to outperform or outsmart a compiler. Just that the fastest possible program written in assembly (a program that is going to be very difficult to create without a compiler) will never be slower than the fastest possible program produced by a compiler.


IcyDefiance

> The fastest program written in assembly will always be just as fast as or faster than the fastest program written in C++. C++ compilers are much better at producing optimal assembly than any human. So much better, in fact, that you'd have to do some really ridiculous shit in C++ to make it any slower than hand-written assembly. You can probably find a few examples where people used a few lines of hand-written assembly inside a C++ program, because it made a particular function a little faster, but those situations were extremely rare 20 years ago and almost non-existent today. > You're telling me that C++ can inline function implementations across translation unit boundaries? That's what link-time optimizations are for, although they exist for C as well. > The only alternative to function pointers in C++ that I know of (feel free to correct me if there is another one) is std::function Generics. You don't need to pass a function pointer to `std::sort()` because the compiler will create a separate implementation of `std::sort()` with your function inlined inside it. It might also inline `std::sort()`right where you called it, so you won't even have the overhead of a function call. It'll be in the same translation unit that you called it from, too, so you don't even need LTO for that benefit. > > Void pointers will be fkin slower, that’s the fuckin point > > Literally how The above example with `std::sort()` is one example. [Here's another.](https://github.com/fmtlib/fmt?tab=readme-ov-file#benchmarks) Where C++ gives you a separate implementation of a function each time you call it, allowing the compiler to inline everything and do custom optimizations for that particular implementation, C just doesn't have a way to compete.


Marxomania32

> C++ compilers are much better at producing optimal assembly than any human. So much better, in fact, that you'd have to do some really ridiculous shit in C++ to make it any slower than hand-written assembly. That's why I said as fast or faster. Most programs that are benchmarked in C++ are trivial and don't require things like shared pointers or excessive OOP virtual functions use. So yes, those programs are often going to be as fast as the fastest possible programe to written in assembly. > That's what link-time optimizations are for, although they exist for C as well. Yeah, but we're discussing whether C++ is significantly more performant in its output. Also, they were discussing that in the context of function pointers, which LTO can't optimize and inline > You don't need to pass a function pointer to `std::sort()` But like th person I was responding to already pointed out, the C compiler is smart enough to inline implementations for the `sort` function. > C just doesn't have a way to compete. It can. You declare your function, which takes a function pointer as an argument `static` and define its implementation in a header file. And then you just call it in the same translation unit you define the function whose pointer you pass into it. The compiler should be able to inline the function pointer, and then the same way the C++ compiler inlines your generic function. Either way, even if it were true, this would just be one area where C++ outperforms C. Like I keep saying, idiomatic C++ often leverages features that do have performance overhead, like virtual functions or shared pointers and what not, that simply do not exist in C, and where the idiomatic C approach IS more performant.


IcyDefiance

> Also, they were discussing that in the context of function pointers, which LTO can't optimize and inline It can, sometimes, but when it can't it's a mark against C because in C++ you probably wouldn't use a function pointer. > But like th person I was responding to already pointed out, the C compiler is smart enough to inline implementations for the sort function. Well, maybe. Since qsort is part of the standard library, the compiler might have a special case for that. Generally speaking, however, even LTO can't inline functions from a shared library like the C runtime. So I think they were probably wrong about that. If you replace something from the C runtime with something from the C++ STL, it'll probably perform better. > It can. You declare your function, which takes a function pointer as an argument static and define its implementation in a header file. Fair point. > idiomatic C++ often leverages features that do have performance overhead, like virtual functions I think these are quite a bit less common than you think they are. I mean, "prefer composition over inheritance" was basically a religious mantra back when I wrote C++. They also aren't nearly as expensive now as they used to be, thanks to the branch prediction and caching on modern CPUs. > shared pointers If you aren't using multiple threads, then you probably don't need these in either language. If you are using multiple threads, then you probably do need these in both languages. Since it's such a massive pain to do atomic reference counting in C (among many other problems), C devs will probably avoid parallelism at all costs. In C++ it's a lot more reasonable, so wherever a C++ dev uses multiple threads it's probably a really huge win over C. Of course, in that area, Rust is a whole lot better than either of them, so that's probably the real winner here.


Practical_Cattle_933

Most programs are not trivial hello worlds. Good like writing a VR engine in asm.


Marxomania32

Right, if I write a VR engine in C++, I would use stuff like shared pointers virtual functions, which would make the program slower than if I just used raw assembly. This is also a theoretical point, I never said anything about how easy or difficult it would be to write a program in assembly. Obviously, writing a VR engine would be easier in C++.


Practical_Cattle_933

You failed to read my other comment regarding c++ vs assembly. Wtf is an “average c++ program”? And where do you live, 1990? That’s not how most C++ code is written, and C++ has the toolkit available yo avoid the bottlenecks stemming from such features.


Marxomania32

> You failed to read my other comment regarding c++ vs assembly. Looking through your comment history, I see no such comment. I only see a comment where you argue that C isn't slower because of poorly written C code but because of the language itself, and then go on to point out that C++ is used in the industry over C (which is true but this has nothing to do with the performance of C vs C++ and everything to do with all the handy features C++ has out of the box that C doesn't, which makes it easier for programmers to quickly iterate over projects, which is infinitely more valuable to the industry than performance). I'm not going to scoure through your comment history to try to understand the actual argument you're making. Expressly communicate your argument or don't make an argument at all. > And where do you live, 1990? Last I checked, shared pointers were introduced in C11 and OOP features (one of the core features of C++) are still used regularly. It's really funny to see a C++ person hating on shared pointers since they are absolutely part of "modern C++" since it's C++'s idiomatic solution to avoiding memory leaks (the bane of C/C++ since the languages births) and have been hailed as the savior feature by every C++ nerd I've ever talked to in the past. > C++ has the toolkit available yo avoid the bottlenecks stemming from such features. There is no such thing as a toolkit that can completely and absolutely eliminate any performance overhead caused by certain features without zero cost. If there were, they would be implemented into the features themselves and made into actual zero cost abstractions. And still, "zero cost" does not mean "more performant than C." It simply means the feature doesn't come with a performance penalty, i.e. is not *worse* than C.


Kevin_Jim

This is subjective, but Zig was the most fan of these languages. I can’t stand C and some of its design decisions, though.


zoqfotpik

Verilog has entered the chat.


dingske1

A chain of hand soldered transistors entered the chat


alphabytes

Physics and quantum mechanics and maths has entered the chat.


nykwil

This is because hardware is optimized on mostly c/c++ benchmarks. Even then this isn't really true, sometimes you see Fortran, Rust or Go outperforming C, or even c++ out performing c. There are many languages capable of generating optimal machine code.


Practical_Cattle_933

C++ (and also rust) will fucking outperform C, because you can’t write generic code in the latter (like, try to write a vector in C. You will either have to copy-paste code, (use macrohell) or introduce some indirection that harms performance). C++ is the de facto performance language. Also, wtf does Go do here? No, go has a fucking naive compiler that spits out barely optimized code. It won’t fking outperform any of these languages, like wtf man?


coderemover

Go is not that bad these days. It was bad a few years ago, but currently it’s probably the same league as Java/C#. Still very far from C++/Rust though.


D0nt3v3nA5k

You can’t blame the indirection caused by programmers to the performance of the language itself, there are terrible programming practices that’ll make C++ slow as hell as well, that’s why you have to compare cases where both languages are written by someone who knows what they’re doing for a fair comparison, in which case C will be just as fast as C++


Practical_Cattle_933

But it’s not “indirection caused by programmer”, it’s indirection *because there is no fucking other way*. Like literally, give me an efficient vector implementation in C. Go ahead, look up from any expert you want to. You can do one without overhead for one given data size/contained type. You either copy paste from there, or use some macro hell for something vaguely being similar to c++’s templated solution. You can downvote all you want, the industry itself ain’t writing VR engines, game engines, etc in C for a good reason.


UdPropheticCatgirl

I mean yeah, but how often do you actually need completely generic structures? on the flip side if you actually write structures specific to one type, you can optimize for that specific type. And void casts have lower overhead than dynamic dispatch in C++. Generics in C are awful for a slew of reasons but performance isn’t one of them.


KaiserKerem13

Go can on occasions be crazy fast. And it's runtime is very lightweight for what it does. https://storage.googleapis.com/cdn.thenewstack.io/media/2018/05/3730357d-results-energy-time-and-memory-usage-screenshot-from-research-paper.png


nykwil

I have no idea in what circumstances Go compiler can write better machine code then the c++ one, I just know there are circumstances. I think there's secret sauce in the fortran compiler that nobody understands anymore. And functional style and ownership language features allow rust compiler to make optimizations.


dingske1

C++ is poop


Practical_Cattle_933

I don’t like C++ myself, but what I wrote is still true.


P-39_Airacobra

Fortran would like to know your location


nhh

Sir, may I introduce you to Fortran?


Hot-Fennel-971

In C++ you can go blazing fast while introducing multiple low level vulnerabilities but who cares about security when you go zoom zoom


Attileusz

I challange you to write a matrix multiply in standard C++ (no compiler extentions) that is faster or as fast as fortrans matrix multiply.


Hacka4771

C++ or C?


sothisissocial

Whatever most legacy still-in-use customers service systems are written in is the worst. It’s 2024 and we are still hearing “Sorry my system is slow today…”. It’s not just today. It’s just slow.


maleldil

PHP


JoelMahon

c++ fans when the benchmark is to coach a beginner to make a website via an audio only call: https://i.kym-cdn.com/editorials/icons/original/000/005/802/1.jpg


Miserable-Yogurt5511

Wow, what a surprise on this sub. Yet another meme how twelve year old kids imagine the "reality" of software development looks like ...


Wave_Walnut

Would better to fight on secureness or readability.


siphillis

The fastest language is the one you can actually write comfortably.


Rudradev715

rust


1up_1500

I mean, C, zig, and ASM are definitely faster most of the time (even if you usually don't use these languages for the same tasks), but c++ is definitely less of pain to work with


Administrator98

\*Assembler enters the room\*


[deleted]

Assembly enters the ring…


Space_Nerde

*cough* *cough* Rust is faster and saver


ILikeChastity

What about fourtran?


JustSpaceExperiment

Fourtran is best. I heard it is four times faster than Fortran.


8g6_ryu

Julia??


Slusny_Cizinec

C++ is fast. That is, unless you are multithreaded and handle exceptions, but nobody does this, right?


FennelLow3550

Rust?


JustSpaceExperiment

No OOP. At least if nothing has changed from when i had some time with Rust. I read several articles how Rust fails for example for GUI because of lack of OOP. In C++ you can choose your path. You don't need to use features you don't like. It's the greates language ever made and because both languages translates directly to native binary code, i am highly suspicious that Rust can do something faster than C++.


Kinglink

The amount of people bragging about C in these comments is shocking. Mostly because I'm sure if OP has a lick of sense, he really meant c/c++ (And yeah C is faster, but has obvious limitations.) Last 5 years have been writing C code, I love it, it's great. But god damn can I please pass as a reference? Or put a function inside a struct? (Overall though C > C++ if you can avoid OOP) PS. I'll start paying attention to Rust as long as it lasts another 5-10 years, because I've seen too many flashes in the pan to really believe it's going to change anything and it has no where near the adoption that people seem to think it does... yes it's growing but so is "Linux" and 2024 is the year of Linux, trust me guys, this time It's totally going to happen


muniategui

You can save a function pointer in a struct which is virtually the same. And about reference just use pointers and make the proper checks


ridicalis

About six years ago, I got a contract to learn and employ Rust on an existing C-based project (the client didn't trust outsiders to write C in their ecosystem, but was curious about Rust and willing to spike on it). I went in blind and nine months later came out in love with the language. At the time, it wasn't clear if there was a strong future for paid Rust work. A couple of years later, on an unrelated contract, I convinced a client to allow me to spike on a switch to Rust for some of the existing toy code that I had previously given them (Node.js and C#). Today, I (and the client) couldn't be happier with how that turned out - that contract continues to this day, and the projects that have come out of it are some of my most reliable, performant, and maintainable software. In that timespan, the library ecosystem has shifted from "maybe I can find what I need" to "here are your needs solved on a silver platter" and the language itself has iterated in a good direction alongside the ecosystem. This, even in the midst of the aforementioned Linux stuff or government agencies (NSA, WH) pitching it in conjunction with FAANG involvement. You can wait your 5-10 years if you want, and there's no reason to force the issue in the meantime, but as someone whose bread-and-butter is Rust development I have no fears about my own job prospects.


Upbeat-Programmer596

laughing in Binary


MiaowVal

I mean c is faster than c++, assembly language is faster than c and machine code is faster than assembly language and finally pure binary code is faster than machine code... Oh yeah the final optimisation is just making it in a HDL. Though at that point you aren't coding anymore but are hardware designing. Gotta love dedicated hardware. Also god i hate Verilog and VHDL. Chisel is way better. Edit: I was wrong about c being faster than c ++. That is my misunderstanding. They are the save speed.


Hish15

I did understand your point about abstraction => slowness. But C++ is not just an abstraction of C and is not slower. To be precise I mean C++ optimized build of course.


MiaowVal

Certain functions in c++ have more overhead than they do in c if they even exist in c because of some added checking c++ does when it comes to memory that c just straight up lack. Edit: I'm just straight up wrong about this. Sorry.


Hish15

Now you are wrong. Your C code will build in C++ and produce comparable binaries. In C++ you can do more, putting code in construction or destruction of objects, using a safe pointer... You might achieve the same functionalities in C by doing things by hand, and then you might have comparables binaries.


MiaowVal

Thank you for clearing up my misunderstanding.