Why (most) High Level Languages are Slow (article)



  • Guy goes into performance problems with modern GC languages (C# in particular). Nice article. Some things I didn't consider before (mostly because there was little pressure for localized performant code).



  • Well that's great, but it's kind of like writing an article entitled, "why Ferrari 458 can't haul 3 tons of gravel".

    High Level Languages are "fast" where it counts: development time.

    Everything else you can solve by throwing more cheap CPUs at it.



  • @cartman82 said:

    (mostly because there was little pressure for localized performant code).

    And that's why this article rings somewhat silly to me. In almost all business applications, you're neither CPU nor RAM-speed bound. It's either the HDD, the network, or - usually - the user.

    Whether your code does the processing in 1, 10 or 100 microseconds doesn't really matter if there's an user behind the monitor clicking a button and waiting for results. And even less if you then take 100 times that to write those results to disk.


  • I survived the hour long Uno hand

    Does anyone who seriously cares about optimizing runtime performance not write in C these days?



  • @Yamikuronue said:

    Does anyone who seriously cares about optimizing runtime performance not write in C these days?

    (because God dammit we've learned JS and now we'll do everything in it!)


  • sockdevs

    As @Maciejasjmj says this sort of thing is important in CPU bound applications, and to a lesser amount to Memory bound applications. Those applications are incredibly rare these days. outside of academia or research applications that do large amounts of data crunching HLLs perform just fine where the application is primarily HDD bound, or network bound, or even user bound.

    when your application is user interaction bound with reaction times measured in full seconds 230 cpu cycles (about 0.000000071875 seconds at 3.2GHz) is meaningless.


  • sockdevs

    You have to declare your data types as struct up front – which means that if you ever need this type to exist as a heap allocation then all of them need to be heap allocations.

    IIRC, the C# spec doesn't mandate that structs can't be allocated on the heap; that decision is left up to the compiler writer. So that blows that argument out the water.

    which means that in order to pass a range of elements from an array you have to create an IEnumerable, which means allocation (boxing)

    Really? I suppose it depends on how you create the IEnumerable, but I'm not convinced.



  • Or you can get an implementation that has a JIT or something, or which can translate into fast C and then compiled... And then you get magical 1.5× — 4× performance by doing exactly nothing. Anyway, while bit counters are counting all the bits manually and doing clever optimisations no one can understand later, we the high level people are moving towards the languages and environments where we just state our problems and let the machine figure out the solution.

    It already kinda happens with SQL, functional programming paradigm. I just wish Prolog wasn't such shit.



  • @wft said:

    Prolog

    Trigger warnings, dammit.


  • I survived the hour long Uno hand

    @Maciejasjmj said:

    http://asmjs.org

    note the word "seriously". JS fanatics are their own kind of nuts.



  • @Yamikuronue said:

    JS fanatics

    I'm just waiting until they get a JIT JS compiler, node.js, asm.js, and one of those billions Javascript-with-types languages together and accidentally reinvent programming.



  • Small step at a time. I just wish Javascript got integers, for starters.



  • My observation is that it's not a language that's slow, it's a programmer with bad habits that's making it slow.

    You won't gain much if you write Java- or C-style code in Python. I remember a refactoring not only being clearer, but kicking the performance somewhere like 6x.

    Sooner or later, learn the language's idioms and use them, simple as that.



  • @Everyone

    Yup. C# (and Java) makes certain tradeoffs that make them great for almost everything - except low-level high performant code, like you'd need in videogames or video processing etc.

    We already knew that.

    My big takeaway is that, if I ever do have to optimize some algorithm, optimizing data structure is much better bet then going for code performance. AND you probably can't do that in GC languages easily.



  • @Yamikuronue said:

    JS fanatics are their own kind of nuts.

    When your only tool is a hammer...



  • So that's when you clench your teeth and learn how to do interop with native code.

    We've known that since, well, managed languages were introduced.



  • @cartman82 said:

    Yup. C# (and Java) makes certain tradeoffs that make them great for almost everything - except low-level high performant code, like you'd need in videogames or video processing etc.

    And yet the top-selling game right now was (originally) written in Java, and hundreds of successful games have been written in C#.

    And extremely graphically-demanding games written in C or C++ still only use maybe 40% of my mid-range Intel i7. Max.

    So the case for using C/C++ for games is... well, it's really shitty and has been for years.

    The reality is: even high-end video games spend most of their time waiting.



  • Interesting...this helps explain a lot about an experience I had converting something written in C to target ILASM with a C# runtime (probably about a 10 years ago). In C it was quite fast, but it was a real dog using the CLR. I'm sure there were a lot of cache misses.


  • sockdevs

    @blakeyrat said:

    The reality is: even high-end video games spend most of their time waiting.

    Especially nowadays, with so much of the heavy lifting farmed off to dedicated hardware by way of PhysX and stuff like that.



  • @blakeyrat said:

    High Level Languages are "fast" where it counts: development time.

    @Maciejasjmj said:

    In almost all business applications, you're neither CPU nor RAM-speed bound.

    :rolleyes:

    Do you guys think that you're refuting something in that post?



  • Yeah, especially because these days, coders are shooting mostly for console interoperability rather than top performance.



  • @RaceProUK said:

    IIRC, the C# spec doesn't mandate that structs can't be allocated on the heap; that decision is left up to the compiler writer. So that blows that argument out the water.

    But what does the dominant compiler writer do? And what do others do? AFAICT, you haven't blown anything out of the water here.


  • I survived the hour long Uno hand

    @blakeyrat said:

    the top-selling game right now was (originally) written in Java

    Minecraft is slow as hell and has ridiculously high requirements.... but nobody cares because it's fun. Well. Until my husband's laptop overheats trying to play it. But Minecraft isn't proof that Java can be performant, it's proof that casual gamers don't give a rat's ass about performance.



  • Asm.js makes perfect sense if you consider the context.

    We have a platform (web) that is supported on an extremely wide variety of devices (more than any other platform, I'd say). And it only runs javascript code.

    We want to turn it into a "real" programming platform, which means supporting other languages. We could try to add some low level bytecode language you can compile to, which would require updating every single device that supports the web (very hard, considering you have to get Microsoft, Google, Mozilla and Apple to agree), or we could make javascript the low level bytecode language, so that you can compile code from whichever language you want to asm.js and it will run on older and newer browsers alike.

    And eventually once there is enough asm.js code in the wild, all browser vendors will optimize for it, and the cycle is complete.


  • sockdevs

    @boomzilla said:

    But what does the dominant compiler writer do?

    Nothing that couldn't change in the next version. The point is it's a compiler implementation detail, not a feature of the language.



  • @RaceProUK said:

    The point is it's a compiler implementation detail, not a feature of the language.

    I think you me and the author would agree on that, but it doesn't change his point (assuming that's how the compiler works...I have no idea and I'm taking his word for it, which no one has contradicted).



  • @Yamikuronue said:

    Minecraft is slow as hell and has ridiculously high requirements.... but nobody cares because it's fun. Well. Until my husband's laptop overheats trying to play it. But Minecraft isn't proof that Java can be performant, it's proof that casual gamers don't give a rat's ass about performance.

    Is that supposed to be a refutation of my statement, or what is this?



  • @anonymous234 said:

    Asm.js makes perfect sense if you consider the context.

    We have a platform (web) that is supported on an extremely wide variety of devices (more than any other platform, I'd say). And it only runs javascript code.

    We want to turn it into a "real" programming platform, which means supporting other languages. We could try to add some low level bytecode language you can compile to, which would require updating every single device that supports the web (very hard, considering you have to get Microsoft, Google, Mozilla and Apple to agree), or we could make javascript the low level bytecode language, so that you can compile code from whichever language you want to asm.js and it will run on older and newer browsers alike.

    And eventually once there is enough asm.js code in the wild, all browser vendors will optimize for it, and the cycle is complete.

    Obligatory:


  • I survived the hour long Uno hand

    You seem to be saying it's not CPU-bound. I'm expanding that to say that even if it was, it wouldn't matter, because performance is not important in this type of game.



  • @Yamikuronue said:

    You seem to be saying it's not CPU-bound.

    Well I don't play it. You tell me, is it? That's really incidental to my point, which is that it's been many years since a successful game "needed" the performance of C/C++.



  • Heh... @The_Assimilator (sounds like the same guy) missed the point as badly as @blakeyrat and @Maciejasjmj:

    Your argument basically boils down to “let’s go back to living in caves and writing assembler because it’s fast”. Strangely, 99.99999% of people who use C# don’t have a problem with its performance. The tiny minority that does is either doing something wrong, or they write their code in low-level languages and deal with the cancer of manual memory allocation. They also don’t write blog posts that complain that high-level languages are slow because they are high-level languages.


  • Discourse touched me in a no-no place

    @blakeyrat said:

    maybe 40% of my mid-range Intel i7. Max.

    :wtf: your 5820K is not mid-range unless you're considering the entire range of Intel's product line, including the 18-core ones. And if you are, that's not how that word is normally used.


  • :belt_onion:

    @wft said:

    Small step at a time. I just wish Javascript got integers, for starters.

    it does if you use TypeScript. :frowning: (i guess it's technically "number", not "integer" though...)



  • @FrostCat said:

    your 5820K is not mid-range unless you're considering the entire range of Intel's product line, including the 18-core ones. And if you are, that's not how that word is normally used.

    Ok thank you for being a pedantic dickweed.

    That affects my point... ... ... how?


  • Discourse touched me in a no-no place

    @blakeyrat said:

    That affects my point... ... ... how?

    I'm not actually going to argue your base point. Even on a dual-core Pentium Minecraft's not CPU-bound, unless you're using some ancient machine with mobo-integrated graphics from before Microsoft was putting GPUs in Pentiums.

    I was actually agreeing with you except for the idea that you have a mid-range processor.



  • @FrostCat said:

    I'm not actually going to argue your base point.

    Then why did you post it? You got some major shoulder alien action going on right now. I guess you've showing us all about the "other side" of StackOverflow right now! The side where you just type random shit and nothing makes any sense!



  • @boomzilla said:

    missed the point

    About which you might want to enlighten us. Because all I get is "managed languages don't do well in CPU-bound applications compared to more bare-metal ones". Whoop-de-doo, no shit, next time you'll be telling me compilers don't always generate perfectly optimal code.



  • And he told us why it happens with C#.

    But it's "silly" to you because it only matters to some specific things, which don't matter to you. Which is fine that it's not important to you. But that's not what you posted. So your comment comes off kind of silly to me. Whoop-de-doo, no shit, next time you'll tell me that knowing how to calculate compound interest isn't useful for a physics simulator.


  • Discourse touched me in a no-no place

    Man, this is some really weak trolling. You wanna step out, maybe get a latte or a bottle of whiskey, and try again in a bit? I'll wait.



  • I don't really care why it happens, except as a trivia. It happens. You can hardly do shit about it. It doesn't matter most of the time, and when it does, then you have other tools for the job.

    What's silly is that it states the most obvious facts (managed languages are slow because they do expensive garbage collection - well fuck, that's the point of managed languages), tries to argue one philosophy over the other as if it was The Obviously Right Thing (no, efficiency is not the only thing you need to care about when you design a language, nor is it one that needs to be considered "up front"), and generally treats a sensible tradeoff like a flaw.



  • @Maciejasjmj said:

    I don't really care why it happens, except as a trivia.

    So STFU about it instead of effectively saying, "You're a retard for looking into this." OK, that's slightly hyperbolic.

    @Maciejasjmj said:

    What's silly is that it states the most obvious facts (managed languages are slow because they do expensive garbage collection - well fuck, that's the point of managed languages),

    Goddamn. Why am I talking to you about this? It's like you didn't even read the article if that's all you got out of it. Yes, he mentioned GC and how it can cause problems, but he was pretty up front about cache vs memory latency as the performance killer.


  • sockdevs

    @boomzilla said:

    but he was pretty up front about cache vs memory latency as the performance killer.

    You can mitigate a lot of that with profile-led optimisation. Which, if you're that worried about performance, you should be doing anyway.



  • @RaceProUK said:

    You can mitigate a lot of that with profile-led optimisation.

    It seems like that would depend on how the allocations play out. Or you do a lot of the messy stuff he talks about in the article (which means non-idiomatic C#).



  • @blakeyrat said:

    And extremely graphically-demanding games written in C or C++ still only use maybe 40% of my mid-range Intel i7. Max.

    Have you ever tried to figure out what they are bound by? If it's waiting for memory accesses, well, the original blog post just makes the point that that's the important factor. If it's for IO, well, yeah, you have a point. For vsync or something like that, ditto. If it's for GPU work ... well the GPU suffers from the same problems as the blog post explains, except much worse (tiny caches, horrible penalties for misaligned/scattered memory accesses, ...).

    Besides, as somebody mentioned, the real optimizing work goes into making stuff run well on consoles, which have way weaker hardware. Even for PC-only games, it's probably optimized with a low-end machine in mind - it's gonna run well less bad on your middle-to-high end machine anyway, so who cares about fully utilizing the CPU cycles there.


  • sockdevs

    @Yamikuronue said:

    JS fanatics are their own kind of nuts

    /me bows

    Thank you! thank you!


  • sockdevs

    JS has some nice things about it, but for serious work, give me .NET or give me something as good :smile:


  • Discourse touched me in a no-no place

    @wft said:

    Or you can get an implementation that has a JIT or something, or which can translate into fast C and then compiled...

    It's more usual to go to something like LLVM instead now. It's about as difficult as targeting C, yet it's easier to integrate the libraries than a full C compiler. And goodness me, it does a nice job with the code that it generates…


  • sockdevs

    well yes.

    but for fun JS is hard to beat.

    for me at least. ;-)



  • @cvi said:

    Have you ever tried to figure out what they are bound by?

    Nothing. Time I guess.

    The purpose of the game engine is to cram shit into the GPU. It just means that:

    1. Shoving the shit at the GPU (including the physics in modern games) is quick enough that 60 FPS is no challenge whatsoever, and
    2. Doing all "the rest of the shit" (AI, loading in new textures, sound mixing, etc.) happens far faster than it absolutely needs to happen.

    So what Skyrim's "bound" by is "running the combat AI too fast for the player to react". I guess? If you phased it that way?

    @cvi said:

    Besides, as somebody mentioned, the real optimizing work goes into making stuff run well on consoles, which have way weaker hardware.

    Again: the Xbox 360 has tons of games written in C# on it that are highly successful.


  • Discourse touched me in a no-no place

    @blakeyrat said:

    Doing all "the rest of the shit" (AI, loading in new textures, sound mixing, etc.) happens far faster than it absolutely needs to happen.

    I think most of those things are left to a library that handles the bulk data movement for the programmer. It's only really the AI that tends to stress things now, and only when trying to do things like actual advanced planning, so that's strategy games only really. Other types of games tend to have AIs that just pick between a small number of immediate options that the programmer identified as being usually relevant to the agents in question; they're typically very easy for the gamer to predict the behaviour of when there's only a small number active.


Log in to reply
 

Looks like your connection to What the Daily WTF? was lost, please wait while we try to reconnect.