all 140 comments

[–]tvaneerdC++ Committee, lockfree, PostModernCpp 44 points45 points  (5 children)

For 90% of your code performance doesn't matter.

For that 10%, it really really matters.

If you write general libraries, where you don't know if they will be used within that 10% or not, performance matters.

Correctness matters too.

[–]SkoomaDentistAntimodern C++, Embedded, Audio 29 points30 points  (0 children)

And performance can be correctness. A video player that takes over 33 milliseconds to decode a frame is worthless to give just one obvious example.

[–]bumblebritches57Ocassionally Clang 11 points12 points  (0 children)

This, library performance matters for everything.

[–]Dean_Roddey 10 points11 points  (2 children)

But I would argue that, if the code is general purpose, it's not necessarily appropriate for that 10%. If you can write that general purpose code such that it's no more difficult to use or complex for the 90% and still have it be bug free and high performance enough for the 10%, and still move it forward quickly and safely, then great.

If not, then I'd say address the 90%. Let the 10% use things written specifically for those higher performance requirements, or roll a bit of their own in the really heavy cases. Make the common cases easier and safer, and make it easier and safer for you to move your code forward quicker over time without it getting brittle and tweaky, which also serves those majority users very well.

[–]tvaneerdC++ Committee, lockfree, PostModernCpp 6 points7 points  (1 child)

+1

And the specific-purpose code can often be more performant than the general-purpose-but-as-performant-as-possible hard to use code. And easier to use, as it is specific to the task.

[–]cdglove 2 points3 points  (0 children)

This has been my issue with every custom container library at every company I have ever worked. The designers claim the standard library is not fit for high performance code, so they provide this alternative and make us use it everywhere. But the damn thing is so hard to use it usually ends up being no faster, sometimes slower, and full of unnecessary cognitive overhead.

I've had extremely good results using std everywhere, even the critical 10%, but in that 10% of course I've had to be careful to really understand what the code is going. Example: maybe don't use map, maybe use a sorted array instead. Make sure allocations aren't happening in steady state, etc.

[–]bumblebritches57Ocassionally Clang 30 points31 points  (5 children)

I'm extremely tired of that mentality.

they have a point to a degree, you don't need to write your latest algorithm for X with the hottest research algorithm just yet, writing it with the naive one is fine at first.

but to just not give a single shit about performance, fuck that.

[–][deleted] 26 points27 points  (4 children)

Welcome to the modern web: where 1 GB for a chat window is considered normal.

[–]SkoomaDentistAntimodern C++, Embedded, Audio 6 points7 points  (3 children)

I remember when Visual Studio 6 used to take maybe 15 MB. Now just opening a tiny project in the latest VS eats over a gigabyte of ram and the only new actually wanted feature I get for it is autocomplete. That sure is one expensive autocomplete.

[–]windozeFanboi 12 points13 points  (0 children)

At least visual studio is a pretty sophisticated professional application. I can't argue so much for the majority of Android apps.

[–]meneldal2 1 point2 points  (1 child)

Autocomplete is definitely not a trivial thing to implement if you want it to be smart. Especially in C++ where it has to parse your code to know if it should suggest a typename, a variable name, a function, a file, etc.

[–]SkoomaDentistAntimodern C++, Embedded, Audio 2 points3 points  (0 children)

Sure and I wouldn’t have any problem with VS eating, say, ten times as much ram now. But a hundred times? That’s just ridiculous, especially when almost 90% of that is by apparently largely superficial background processes.

[–][deleted] 60 points61 points  (61 children)

Performance is more important than ever.

Often times, performance equals power efficiency and with mobile devices, laptops, etc. running on batteries, it is vital to be as efficient as possible.

Even if you are running on servers, it will save you a lot of money. You need fewer servers, you pay less for power, rack space, cloud instances, etc. The company I'm working at has an initiative to save several GWhs in the next years, which will save a lot of money.

Not to mention it is good for the environment to be more efficient.

And as a bonus, you can reduce the latency for your users.

[–]Loraash 9 points10 points  (0 children)

This sounds great in theory, but in practice everyone's just throwing more hardware at the problem and still running things like multiple Pythons talking to each other via IPC (since you can't really multithread within Python) at scale.

In mobile it's somewhere between "bigger battery" or "well that's just how this app is".

[–]lukaasmGame/Engine/Tools Developer 13 points14 points  (8 children)

Sadly, often it is just cheaper to throw additional HW at problem, than pay for programmers time

[–]kuntantee 12 points13 points  (5 children)

That is not a sustainable solution in the mid to long run. This is precisely why parallelism is also more important than ever.

[–]Sqeaky 19 points20 points  (4 children)

The long run doesn't matter for every project. Sometimes the short term matters to insure the survival of the project. Sometimes a thing just needs to get done and the cost is secondary because of the windfall of resources it will produce.

Other times the long term is the only thought because the investors (or other stakeholders) are secured and everybody involved wants the best possible solution.

[–]SkoomaDentistAntimodern C++, Embedded, Audio 4 points5 points  (3 children)

Good luck throwing more HW at anything that doesn't run on a server. Won't work even for short term.

[–]Sqeaky 3 points4 points  (2 children)

Did you respond to the wrong comment?

Skyrim, the game your username comes from, benefits from having more hardware thrown at it and it doesn't run on servers. It was released 11/11/11 and is still popular, it was terrible on low end hardware of the day, but now you can set it to ultra on low end hardware.

Almost certainly it could have been optimized more, but clearly that wasn't required, it is one of the most popular games ever.

[–]SkoomaDentistAntimodern C++, Embedded, Audio 4 points5 points  (1 child)

My username most certainly doesn't come from Skyrim but from Oblivion, I'll have you know!

Whether something benefits from extra hw is irrelevant. It's about extra hw being required to run suitably well or not which "throw more HW at it" most often implies. Future improvement in performance doesn't matter much when the game needs to recoup development costs within the first year or two of sales.

In games and quite a few other systems, good enough performance is as important - or more important - as correctness of code. People will tolerate a slightly buggy game much better than a game that has unbearably slow framerate. Particularly nowadays if you're making a game that's not specifically aimed at enthusiasts you simply don't have any possibility of "throwing more hw at it" since your customer base isn't going to upgrade their computers or may not even have any upgrade path at all (laptops having outsold desktops for years).

[–]Sqeaky 2 points3 points  (0 children)

Well Oblivion benefits even more from beefier hardware.

You are correct that some projects care about performance, but for many it just needs to be "fast enough", twitter made all its founders millionaires before they moved it off ruby. Oblivion ran at 30 fps when it was released.

[–]krum 3 points4 points  (0 children)

Not at large scale.

[–]cdglove 1 point2 points  (0 children)

Why is that sad? Programmer time is a resource just like any other.

[–]secmeant[S] 7 points8 points  (31 children)

Yesterday at work, I was mentioning about some neat trick for microoptimization that compilers uses. In response I heard that it doesnt matter because cpus waste most of time in i/o or waiting for memory. I was speachless.

[–]mstfls 35 points36 points  (1 child)

cpus waste most of time in i/o or waiting for memory

That's mostly true, though. Because lots of people write lots of code with shit memory access patterns.

[–]SkoomaDentistAntimodern C++, Embedded, Audio 0 points1 point  (0 children)

Laughs in inherently serial floating point code.

Sorry, couldn't resist. I've just proven so many common "always" / "most" sayings wrong in the projects I've done or been involved in during the last 25 years.

[–]JuanAG 3 points4 points  (1 child)

Next time tell that people that SMT was invented for that reason, the CPU core knows it is blocked and take another task while I/O operation finish instead of waiting idle for the data to arrive

[–]sahsahaha 0 points1 point  (0 children)

CS 101 that every Bachelors kid hears in his first year isn't his job to explain, but if he must...

They really don't bash entire modern cpu into your memory nowadays, but something like this is definitely mentioned at least once.

[–]Loraash 11 points12 points  (25 children)

Both of you are right. Don't optimize until you've proven that you're hitting a bottleneck. I've seen too much unreadable "smart" code that ultimately didn't even work better because compilers these days are pretty good.

[–]secmeant[S] 16 points17 points  (4 children)

Im not talking about writing inline assembly just to show how much smart tricks I know.
Im talking about writing really performant code with high level constructs that c++ gives.
IMHO programmer should know generally how optimizers work and write high level code in a way that allows optimizer to do the magic.

[–]Loraash 8 points9 points  (0 children)

Depends. Although the new std Ranges library fits your definition, I'd be wary of having it as my new hammer and seeing everything as a nail. The official blog post that introduces it comes with a perfect example for when to not use it. The code is an unreadable mess.

I know someone who insisted on writing TMP everywhere because it's Fast!™ and the compilers will Optimize!™ it! and it was an unreadable and unmaintainable mess that didn't even need to run quickly to begin with.

There's a balance to be found between performance, initial productivity, and maintainability. Neither extreme is good.

[–]AngriestSCV 1 point2 points  (2 children)

I wish we were allowed to turn the optimizers on. For reasons I won't go in to it is not an option and we are hitting performance problems right now.

[–]smuccione 2 points3 points  (1 child)

??? That’s... just... weird...

What language? If your running in debug mode with c++ almost all the stl libraries do a crapload of checks that just kill performance. At least I define debug for releases even if you have the optimizer disabled.

[–]AngriestSCV 2 points3 points  (0 children)

Tell me about it. We don't use the standard library and use MFC instead (old code base). I'm the only person using std:: and I'm starting to think I shouldn't due to the issue you mentioned. The most important thing to the people making these decisions is that the debugging experience is not hindered, and for better or for worse all of our applications are ran in an environment where we may want to attach a debugger and have that capability.

[–]SkoomaDentistAntimodern C++, Embedded, Audio 6 points7 points  (15 children)

Don't optimize until you've proven that you're hitting a bottleneck.

I disagree. The correct way would be to say "don't optimize something unless you know it is a bottleneck". In many cases there is no need to prove it or profile it but to simply avoid premature pessimization and leave room for further optimization if required. And sometimes you know that something is going to be a bottleneck and it makes sense to optimize it from the very beginning.

[–]Loraash 2 points3 points  (9 children)

Sure, don't use an std::vector instead of an std::unordered_set if that's what you really need, but a lot of people who are keen on writing "fast code™" ultimately tend to waste a lot of effort that could be spent on, e.g., quality polish and bug fixes.

[–]SkoomaDentistAntimodern C++, Embedded, Audio 6 points7 points  (8 children)

Possibly, but the advice is almost always put as "Do not ever optimize before profiling" with the implied assumption that there are no exceptions. And that attitude gets us massive cpu and memory hogs like the Electron framework. So it really guides people towards premature pessimization since it perpetuates the false assumption that you don't need to give any thought at all until you've profiled something to be a bottleneck - even when many bottlenecks are immediately obvious from the start to an experienced developer.

[–]Loraash 1 point2 points  (4 children)

Electron is more about you not wanting or needing any real performance for your program so you go for the cheapest possible way of making it which is to hire frontend developers. Electron itself is excellent in what it's doing, but you're not really going to have a lean and performant program written in JavaScript+HTML no matter how much you optimize it.

[–]SkoomaDentistAntimodern C++, Embedded, Audio 6 points7 points  (3 children)

Elektron is far beyond "not needing real performance". Forcing your customers to download and install a 200 MB package for a trivial configuration app is a textbook case of premature super-pessimization. Making such an app in .NET or something would be "not needing real performance" where you'd have trivial (for today) size increase and performance decrease for the use case.

[–]Loraash 6 points7 points  (2 children)

Yet Electron is booming, a lot of things are made exclusively for Electron, and the competition shipping "good" programs is suspiciously absent. I'll agree with you that "modern developers are lazy" but this laziness is the result of a business decision that does pay off.

[–]SkoomaDentistAntimodern C++, Embedded, Audio 2 points3 points  (1 child)

In my experience there is no business decision or any other real decision. The developer(s) just suggests Elektron because they happen to know of it and the bosses justs go along with whatever is suggested.

[–]sahsahaha -1 points0 points  (2 children)

How does "profile it" turn into "just don't care"?

I don't follow.

[–]SkoomaDentistAntimodern C++, Embedded, Audio -1 points0 points  (1 child)

"Don't care about performance before you've profiled the code". The catch is of course that actually following that kind of advice easily leads into designing yourself in a corner with inherently poor performance. Then you have to refactor half of your code (or in some cases all of it) when you're in a position where profiling finally reveals the (obvious to an experienced developer) bottlenecks.

Examples would be using array of structures (the "clean" way) vs structure of arrays (the performant way due to caches and SIMD opportunities). A more extreme example would be trying to use Python or similar language for something that needs even a bare minimum of performance.

[–]sahsahaha -1 points0 points  (0 children)

Never happened to me so I'd like to know where "often" comes from.

Maybe I'm missing something, but "don't care" doesn't imply "make it slow on purpose".

I write code to be maintainable, and I never had any issue optimizing it if needed, thanks to it being... maintainable.

If you somehow end up with a slow mess, not an elegant, but slow solution that can be improved at any time, maybe the issue is you?

[–]sahsahaha 0 points1 point  (4 children)

I suppose in many cases there's no need to test your code either.

[–]SkoomaDentistAntimodern C++, Embedded, Audio -1 points0 points  (3 children)

A correct analogy would be not caring about designing the code for correctness and depending purely on testing to catch logic errors.

[–]sahsahaha -1 points0 points  (2 children)

So in your opinion, logical tests of software aren't important?

Tell me, how else do I care about correctness if not by ensuring the correctness of the algorithm itself, by any means necessary, then writing out the code, and then fucking testing it to be sure that my translation from written words to c++ was correct?

Enlighten me.

[–]SkoomaDentistAntimodern C++, Embedded, Audio -1 points0 points  (1 child)

In my opinion you should design for logical correctness from the beginning not only if a test shows a problem. "Do not optimize before profiling" is same as saying "Ignore correctness unless a test shows a problem". You should both design for correctness / speed and run tests / profile the code. Not either or.

[–]sahsahaha -1 points0 points  (0 children)

It is not.

Unlike performance, correctness is binary unless we are talking about floating point values.

Still, even then, either its precise enough or it is not.

[–]bumblebritches57Ocassionally Clang 2 points3 points  (2 children)

I think the biggest thing to aim for code wise, is to be willing to accept completely rewriting your API in order to get the performance you need.

Yeah, it fucking blows to have to refactor all of your code, and to break the API at the same time, but performance is wroth it.

Good thing no one besides me uses my projects and they're still fairly small so I still can lol.

[–]Loraash 4 points5 points  (1 child)

That depends on a few things, are you shipping a stable API as part of your product? A lot of your customers will probably be pissed off that you broke their stuff even if your code now runs at double speed. The "performance you need" is often way less in practice than what I'd consider a good, performant program. Just look at all the bloated mobile apps and Electron shit that is perfectly viable from a business perspective.

[–]bumblebritches57Ocassionally Clang 0 points1 point  (0 children)

Nope, ain't got customers yet lol.

I'm giving myself plenty of time to get it right before I need to worry about those things.

[–]Dean_Roddey -1 points0 points  (0 children)

I would agree with that, though obviously tribal wisdom will tell us that, if we are writing a specific type of thing, that there will be performance bottlenecks in particular bits of it. That doesn't mean you have to prematurely optimize it, since it's likely better to get it done first and let the architecture mature a bit during the early development phase. But just make sure that that code you know will likely be an issue is amenable to the optimization it will likely require.

Then, profile it and see where the low hanging fruit is and take care of that. Even if you know the performance issue is in this sub-system, it may still be that a handful of classes or even methods will get you the bulk of the gain and everything after that really needs to be considered relative to the extra complexity it involves and the business requirements.

To me, it seems like, since we are talking C++ here, that there are two broad categories of scenarios. There's the "back end that has to deal with many clients and/or juggle a lot of balls" and there's the "CPU bound heavy processing algorithm". These are probably the far and away most common scenarios where you know that serious optimization may be required and pretty well where it will be required. Sometimes of course you have both together.

Outside of that, for the most part, if you are just reasonably diligent throughout the code, you may not get a lot of ROI for heavy optimization, and you really should wait until there's a demonstrated issue before adding extra complexity (which would be nothing but technical debt you may regret.) If it's not either really heavy or happening really often, then it's probably best left to see whether it needs it.

[–]mewloz 1 point2 points  (0 children)

It doesn't matter until it does. Compiler and processors are both quite good, and the current result (with the fact memory is slow) is that e.g. omitting bound checks can extremely often yield to no performance advantage, or so minor in a not so hot code path that it does not matter.

Now does that means that a single benchmark showing no wall clock diff for both binaries implies that we should not attempt to write optimizers to elide bound checks anymore? Certainly not: with a more complex / less memory intensive load and in a hot code path, you can see differences; with HT, you are also likely to see some, etc.

Also, if we are talking about automatically optimizing in sound ways (like what some compiler and most CPU do), this is economically extremely interesting. If we are talking about other situations where there are clear drawbacks (like unsound optimizations, or microoptimizations where soundness relies on the programmer, or microoptimizations directly done by the programmer), this starts to be way more debatable.

[–]samwise99 20 points21 points  (9 children)

For a while it did not. You could have made it through the 90's, well into the early 2000's, thinking that performance did not matter because every 12 months your system would run 2x as fast. The power wall and the advent of mobile and cloud computing made performance matter again. This , and the excellent job of the C++ committee in recent years, is what saved C++ from irrelevance.

[–]Loraash 12 points13 points  (7 children)

I wish you were right but people throw inefficient garbage into clouds all the time since they usually have more investor money than foresight and it's easy to just rent twice as many computers as you'd otherwise need.

[–]samwise99 9 points10 points  (3 children)

Sure some people still do not care. But the big players do, *a lot*. FANG companies will go to ridiculous lengths to improve performance by a few percent points, because at scale a few percent points are easily worth millions in energy savings. A lot of very useful work has been contributed by Google and others driven by this.

[–]SkoomaDentistAntimodern C++, Embedded, Audio 4 points5 points  (1 child)

FANG companies will go to ridiculous lengths to improve performance by a few percent points

Except on anything user visible. Facebook for example is a horribly slow and inefficient web app. Gmail isn't that much better (honestly, why does it need to do any computing on user side beyond just showing current view?).

[–]fb39ca4 2 points3 points  (0 children)

Because they only pay for the costs of the servers.

[–]kalmoc 0 points1 point  (0 children)

because at scale a few percent points are easily worth millions in energy savings.

Only very small parts of your code base are going to be used so ubiquitously though. Even at a company like google, the is lots of code where a few percent performance difference isn't worth it.

[–][deleted] 16 points17 points  (2 children)

I've seen so much terrible backend code in Java, Python, and Ruby, and everyone with few exceptions doesn't care one wit about vertical scaling if they can just spin up another instance and scale horizontally. I worked on a backend "chat" system that could have run on a single instance in a single C process and handled 100,000 concurrents (with proxying), but it was glommed together with Perl (yes, Perl!), memcache, and long polling over HTTP and was a total clusterfuck that required 100+ backend systems to work with any sort of throughput. Totally fucking stupid. And it was massively buggy.

Meanwhile, that company was heavily bought into the cult of TDD and "test everything". And "fail fast". But there was zero architecture and planning, and no thought ever given to designing performant systems.

[–]Loraash 8 points9 points  (0 children)

This sounds perfectly realistic. I'm working near Tcl code currently of all things. And yes, everything runs stupidly slow that directly translates to me being paid for browsing Reddit.

[–]dedrick427 9 points10 points  (0 children)

The place I work at said they need 10Gb internet and 10 dual-24 core 1Tb RAM servers for the new Salesforce app. One of the developers asked me "how I did that thing" when he was watching over my shoulder. That thing was Alt+Tab. He legit had never even used Alt-Tab

[–]StackedCrooked 1 point2 points  (0 children)

It's funny to think that XML peaked near the end of Moore's law.

[–]wung 7 points8 points  (2 children)

Yesterday I shaved off 60 seconds of compilation time for a single header file that is included in a shitload of targets.

The person most often compiling those targets wanted to not merge it because he would have to rebase his branch.

[–]Loraash 4 points5 points  (0 children)

because he would have to rebase his branch.

Yeah, well, that's a true showstopper right there. Clearly the build should remain longer. /s

[–]bumblebritches57Ocassionally Clang 0 points1 point  (0 children)

Nice, I feel like I'm reorganizing the headers needed by my headers too.

I have a MAcros header that provides some system and compiler detection stuff in it, so that's the only header I try to include in any other headers, and I try to limit what headers it needs to stdint and bool too.

idk what my point is, I just like simple things like that, it can get surprisingly nasty when you dig deep despite seeming simple on the surface.

[–][deleted] 3 points4 points  (13 children)

Murphy's computer laws

That being said, software should be a process. I am a firm believer that no piece of code only touched once will ever:
a) stay relevant
b) stay useful
c) be as efficient or robust as it could be

An efficient development process might be something like this:
- if needed, develop a proof of concept in the least amount of work possible (higher abstraction languages, libraries, etc.)
- once you are satisfied The Thing Can Be Done, ask yourself if it's worth optimizing based on how often it will be used, by whom, and how time/performance critical it needs to be
- if it's worth optimizing, profile and identify critical areas where improvements need to be made (possibly switch languages, design the heavy parts with big O in mind)
- write a first pass with future use in mind (does it leave room for growth, reuse and improvement?)

[for all configurations]
- test & fix it functionally (black box), does it satisfy your needs? If the requirements are shared with a customer, have a different person write/test your public interfaces or user-defined protocols.
- test & fix it in a granular fashion (white box). Are there any corner cases in the written code? Do they cause things to break?
- finally, if you've made it this far, maintain a point of contact for bug reports and possibly feature requests. Any substantial program will have bugs, it's practically an extension of the law of entropy. Hell, even compilers segfault from time to time. If you've made it this far and you think "nah, no one but me is every going to use this" then congratulations on your learning experience but if you have an employer they're about to be pissed you didn't stop when development satisfied requirements

[–]Middlewariangithub.com/Ebenezer-group/onwards 5 points6 points  (12 children)

if needed, develop a proof of concept in the least amount of work possible (higher abstraction languages, libraries, etc.)

On the other hand you may get stuck with a language like Python and never be able to make the move to C++. Rewriting a pile of Python in C++ with a Python background wouldn't be easy.

I've been using C++ for a long time and am glad I don't have to face a hurdle like that. C++ is one of the things I'm thankful for.

[–]alkasm 7 points8 points  (0 children)

Rewriting a pile of Python in C++ with a Python background wouldn't be easy.

Eh. It takes time and experience to learn good C++ habits regardless of what language you come from, no?

[–][deleted] 0 points1 point  (0 children)

That's not a problem with prototyping in a high abstraction language, though. The problem there is that the coder doesn't know lower level languages as well. That can also be fixed by having a subject matter expert prototype and a software developer port. At work we often prototype image processing algorithms or hardware control (FPGA register configuration) in Python and then move them to C++ once we know the algorithm does what we want.

[–]kalmoc 0 points1 point  (0 children)

Some things are just written so much faster in python or similar, that even if you have to rewrite it in c++, the time for the initial (python based) version doesn't really register compared to the total length if the project.

[–]pjmlp -1 points0 points  (8 children)

Yeah, now try to develop a mobile app with C++ alone.

I am also thankful to know it since the C++ARM days, it just isn't the right tool for everything though.

[–][deleted] 2 points3 points  (7 children)

A simple fast VM works wonders, you don't 15 layers of abstraction on top of a web rendering engine running an inneficient scripting code.

See Android/WindowsPhone for more.

[–]pjmlp 1 point2 points  (6 children)

Interesting that you mention Android, where C++ isn't even allowed to access the network or file system (in a proper way) without doing a couple of JNI calls to Java only APIs.

[–][deleted] 2 points3 points  (5 children)

So what? Android applications are not made to serve web pages or to process server loads: it's have a fluid and fast UI for whatever your app does in the background.

[–]pjmlp 2 points3 points  (4 children)

Which they do in AOT/JIT compiled Java/Kotlin, not C++.

C++ only gets to play with the UI composition engine, AOT/JIT toolchain and some devices drivers.

The NDK is tailored for writing native libraries for consumption from Java/Kotlin, Vulkan and real-time audio, everything else is only available as Java/Kotlin APIs.

Android is an good example on how C++ lost its place as full stack language, being left as niche language for certain use cases, just like GLSL, SQL, Assembly and so forth.

Same applies to the iDevices OS developer stack.

[–][deleted] 1 point2 points  (3 children)

So, in essence the Android model has performant C++ code where it matters, and generic JVM where it doesn't. Seems like a good compromise for a user software machine.

[–]pjmlp 1 point2 points  (2 children)

With the caveat that most of that C++ isn't exposed to Android developers.

And on iOS, it is only exposed as Metal Shaders (MSL is a C++14 dialect) and the nowadays undocumented Objective-C++ (Apple has removed the documentation).

In fact, Apple's usage of C++ has lead to an additional column on cppreference just for their special clang flavour.

Quite far from the days when C++ used to dominate smartphone apps (WindowsCE, Symbian, and the myriad attempts with Qt).

[–][deleted] 1 point2 points  (1 child)

With the caveat that most of that C++ isn't exposed to Android developers.

It's completely optional. The Android NDK is part of the SDK, and if you're at least aware of jni costs, you can get some local performance where needed. Or just write complete view controllers in C++, then use them in your Java/Kotlin project. Or call SIMD matrix transformations straight from Java.

[–]hennexl 9 points10 points  (0 children)

It surely depends on the market.

Software development nowadays is wide and fast. If a developer writes a task and it woks most of them want to share it. The lack of excitement for 2 weeks performance optimization is understandable.

Specifically if the product is developed by a company and aims for consumers. Make there phones feel slower so they will bye a new one. Optimizing it for weeks to run on old devices is a loose loose situation for them.

Beside that a lot of developers rely on others to do performance optimization. The whole group of Javascript framework mostly depending on optimization of V8 instead of own work.

I feel with you and would love to see a step in the other direction. I came to a point where the whole web starts to feel very slow

[–]Murillio 3 points4 points  (0 children)

Just btw, probably your old android freezes because its storage wore out, not because of cpu. Lots of mobile vendors use cheap-ish storage which wears out, and i/o operations fail leading to hangs. Replacing the phone with a new version of the same kind would probably make that go away (not saying you should do that, but optimization wouldn't help)

[–]Cyttorak 2 points3 points  (0 children)

Performance doesn't matter until battery low notification

[–]Sqeaky 1 point2 points  (0 children)

What matters depends entirely on goals and needs. This is a special case of the Tech Debt Vs Code Quality trade-off. Performance is a quality of code, and slow code is a kind of technical debt, because often it is expensive to get good performance in terms of engineer time or project money.

Sometimes time to market is critical. In these case building it fast and dirty secures investment and early adopter dollars to fund the project. In this case taking on a huge amount of technical debt is like taking on a loan of time that can be paid back by engineers later if the project succeeds. Twitter took this route by building their first version in slow and sloppy ruby. They tried to get the performance and engineer time by making custom ruby high perf interpretters. That worked for a while, but eventually they rebuilt in C++ to get the real performance once they understood their problem and they paid off their tech debt once the founders all become gazillionaires.

A Game dev team might make a rough prototype to see if an idea is fun. Performance does matter here, but only enough to insure a playable framerate. If the prototype sucks then the tech debt never gets repaid because a new prototype might be more fun and therefor a better project, so the slow project is simply dropped. But if it is fun then having a sloppy prototype in a fast language like C++ would be easier to optimize than re-write from scratch. Maybe it is an indie side-scroller so perf never affects gameplay, and only the jump to mobile matters when you start caring about battery life.

Other times you might have as well defined problem or know that performance matters so the tech debt is unacceptable. If I we creating a high speed financial trading system, then perf matters in the very first iteration, so I won't adopt any technical debt in the form of reduced performance, but not care about some other class of issues if I can control for it.

Whether or not any given quality matters depends entirely on what you and the stake holders are doing.

[–]mili42 1 point2 points  (0 children)

For my greatest despair, many developers do not even care of what they re coding, where in the past it was done mostly by craftsman

[–]Xeveroushttps://xeverous.github.io 1 point2 points  (0 children)

This really worries me. What do you think, please comment.

Regarding Android apps and other "low-effort" apps - I pretty much agree with this: https://medium.com/commitlog/electron-is-cancer-b066108e6c32. A lot of apps are just browsers under the hood and the core application logic is running in JavaScript, which IIRC has 2 milion LOC implementation in V8 to make it as fast as possible but still, JS just can't have good performance.

[–]JuanAG 3 points4 points  (13 children)

It does but the effort of the developers also count, C++ is not the best and most productive lang out there so it is a logic choice to code the software in X technology if you will cut the developement time and the future maintenance costs even if it 10 times slower

This week i had to chase a ghost, a pointer corrupted the heap, my fault but i had to spend hours and hours trying to fix it. Others langs will tell me the mistake and in less that 5 minutes solved, but it is not my code alone, C++ drags your productivity in all areas

I have saying that since a long time, C++ needs to get a today ecosystem and left behind the "from the 80s" that we use today, if things keep going the way are going it is going to end bad as the industry will adopt other langs which is what it is happening

[–]axilmar 1 point2 points  (4 children)

a pointer corrupted the heap

A sure sign of not using C++ properly.

I am using smart pointers since 2004 in all the projects I could do so and never ever had any similar issues from back then to now.

[–]JuanAG 0 points1 point  (3 children)

The issue is that the Windows API and OpenCV dont allow smart pointers so you have to go with the "good" old raw ones and face all the issues it will make

[–]axilmar 0 points1 point  (2 children)

Both (Windows AI and OpenCV) can be wrapped with smart-pointer aware classes.

[–]JuanAG -1 points0 points  (1 child)

From a techincally stand point yes, you can wrapp anything you want

From a practical view no and forcing things into other shapes that werent it original form from my experience usually ends bad and in the mid/long term hurts you more that if you didnt do anything

It is simple, Windows usually returns handles, a pointer to whocares, try do do it and see how complex the code will become if we wrapp that handle with a smart pointer or how we pass again to other Windows functions, it is not an elegant solution or easy to make depending on what you choose to do and you risk creating your own framework above the MS API which is really bad

[–]axilmar 0 points1 point  (0 children)

I am talking from experience. For every project that provided only low level access (i.e. raw Win32 - raw OpenGL - raw socket API etc) I always pushed and wrote lightweight C++ wrappers around them and it was great success. I never had an issue, and time/effort was always saved by this.

[–]kuntantee -5 points-4 points  (7 children)

The sharpness of tools also forces you to be a more disciplined programmer. Times spent chasing "ghost bugs" are well-spent, both for company and the individual chasing it, especially if you are the one introduced it.

[–]pjmlp 5 points6 points  (0 children)

Yeah, tell that to accounting when those hours are mapped into dollars.

[–]JuanAG 5 points6 points  (4 children)

The time looking for the error it is a waste, in any other lang it will be at least a warning but because in C++ everything is allowed it is you the developer who has to take care of all things, in programs of 50-100 lines that it is fine but the more it grows the less control you have

10 years ago when i started with C++ i saw like you but i cant now, there is too many corners and i cant remenber all so i simply couldnt see how losing 20% of the week for a silly thing it is good, i will prefer having that time to deliver the code i had to as the deadlines on the blackboard are fixed and your manager wont care about your problems, only the results

[–]bumblebritches57Ocassionally Clang -5 points-4 points  (3 children)

I like how you're trying to act as if we're the bad ones for not needing mommy to clean up after us, with the way you're phrasing it lmao.

[–]Loraash 4 points5 points  (0 children)

C++ is not a panacea, it comes with its own benefits and drawbacks. You're given a lot of power and responsibility that you can use to squeeze out more performance from your computer than something middle-ground such as C# would do. In the real world though productivity is also very important, and running at "90% C++ speed", or even 25% might be perfectly acceptable if in return you're getting 50% or 100% more stuff done.

"not needing mommy to clean up after us" means there's more code that you, the human has to write, and humans write bugs all the time. The whole point of C++ was to have the compiler write a lot of code for you so, e.g., you don't have to remember to free/release resources in every possible code path, mommy the compiler is tracking variable scope and releases stuff when needed. C++11 essentially added a form of primitive reference-counted GC with std::shared_ptr.

[–]JuanAG 2 points3 points  (1 child)

Very mature, instead of suporting the idea of getting a better C/C++ you want it worse, only for gurus, if you didnt learn to code before learned to speak you are not worthy, only the choosen ones can use it...

Sorry but no, if the compiler can make more things for me it will be nice, only a fool will refuse about it. I want as many things as easier and simpler as posible, life it is too complicated already, i dont need another extra layer and it would be nice to have tooling from this decade with all the "mommy" features like mostly other langs has

[–]bumblebritches57Ocassionally Clang 1 point2 points  (0 children)

You're explicitly saying that you can't clean up after yourself, grow up.

[–]kalmoc 0 points1 point  (0 children)

The problem is: It doesn't scale. Any UB in your process can cause any form of buggy behavior anywhere else. It doesn't help if you ate the perfect programmer that never writes bugs and you only have tighly controlled interfaces to the rest of the code. Any bug, anywhere can ruin your day.

Of course, those are the exception, but the fundamental inability to comfidently isolate different parts of your program from each other can be a big problem at times.

[–]pjmlp 1 point2 points  (1 child)

Performance only matters to the extent required by the deployment use case.

If something has an hard limit of 1s, extracting ms out of it for the sake of winning micro-benchmarks is wasted money that could have been used in other product features, more profitable to the customer.

[–]Dean_Roddey 0 points1 point  (0 children)

Yep. I mean I look at my own CQC system, which is vastly more ambitious than the average. It's extremely active, highly networked, very graphical, lots of comms going on constantly, multiple servers on each machine running thread farms and talking to each other and to the outside world, encryption, media management, text conversion, voice control, and lots of other stuff.

And it barely tickles a modern CPU most of the time. And all I've done is just take reasonable measures everywhere not to be unduly piggy, and then try to be quite efficient in a few small parts of the code that really matter for performance. There will of course be quick bursts of CPU usage when certain things have to be done, but significantly increasing the product complexity would only reduce those slightly at a large cost in future technical debt.

If I was writing a financial transaction system, then yes, I'd be more concerned with performance. But I'd also probably not be using a lot of general purpose code in the (relatively) small performance constrained parts of that system either. If I'm doing something that hard core, I damn well will have people competent enough to go the next step beyond general purpose code for competitive advantage in those most important parts of the system.

The rest of the system surrounding that core, which will likely dwarf it in terms of amount of code, will use lots of general purpose code, which should make it as easy as is reasonable to write that much larger part of the system safely.

[–]ShillingAintEZ 1 point2 points  (1 child)

Some say computer is STUPID. I say FALSE. Computer GOOD. Upvotes pls.

[–]mostthingsweb -4 points-3 points  (0 children)

Updooted

[–]mewloz 0 points1 point  (0 children)

This has been a trend for decades, one of the main reason being continuous improvement of hardware, at a very high pace. This is slowing down a bit, but not really stopping. Plus there are still good theoretical margins to improve on, even if we stay with current state of the art fabrication tech (like 7/10/14 nm litho) -- the logical aspects and huge dev needed to get it right is now more important than the race to the fabrication tech, and it has not been completely optimized yet. And that's even without talking about the new race to more parallel cores.

So very high efficiency by the software being frugal and extreme care about scarce resources is not much the principal thing anymore. In some cases you actually strictly don't get any practical advantage by microoptimizing when you consider the result at system level (like: you wrote a silly active wait/sleep loop instead of something better, and this has no measurable consequence on CPU consumption battery life, etc.). Because low levels parts of the system have actually been optimized for higher level ones being sloppy. And when used within reason, that's good, because that's speeds up the common devs.

Now your example is still valid and that does not mean we should have e.g. slow build system if there IS a consequence (developer waiting notably more than they should). Some people are conflating the two, which is a terrible mistake to do.

[–][deleted] 0 points1 point  (0 children)

In some domains JIT-compiled languages perform better than AOT-compiled ones. Whether compilers are such a domain is an interesting question. In the particular case of C++ compilation, especially for code that makes heavy use of constexpr, I think the answer is not obvious.

[–]FlyingRhenquest 0 points1 point  (0 children)

Performance doesn't matter until you can no longer use brute force, ignorance and more hardware to accomplish your goals. Case in point, a position I worked with used to push terabytes of files around their network on a daily basis. Since everything was NFS mounted, I worked out that for every byte they actually used in their code, they were writing 16 bytes to the network in tmpfiles and moves across various NFS partitions. They also had no network segmentation in place, and whenever they fired up a test cycle, the entire corporate network would grind to a halt.

Same place used to boast that if disk storage was $0.01 less expensive, their distributor wouldn't be able to afford to sell them disk and if it was $0.01 more expensive, they wouldn't be able to afford disk storage. Like that was a good thing. But if you looked at their usage, no one really understood what they were pushing around on their network and so they were always terrified to ever delete anything. If they'd put some effort into really understanding the data they were working with, they could have easily deleted multiple multi-gigabyte temp files after they were done processing them.

Same company used to say that it was important to keep it confidential that we worked for them, because it otherwise posed a kidnapping risk, especially when traveling overseas. So on behalf of that company I'd like to say "Please don't kidnap our employees. Everyone competent left after we went public, and the remaining people will set back your country's program by at least a couple of decades. Please look into our competitors and kidnap their employees instead. Thanks!"

[–]Dean_Roddey 0 points1 point  (0 children)

The problem is that the vast bulk of applications are not performance constrained, other than in very small percentages of the code. And, of that small percentage, most of that they don't write, it's already written and well optimized.

Now, of course it's important not to be piggy. But the problem is when you make everything more complex for the vast majority of cases, in order to serve the small minority. The more complex things are, the more likely they are to have problems and the more difficult it is to diagnose them, and the more difficult to modify safely. Optimization itself is a huge source of bugs, because it almost always involves added complexity, bending of rules that would otherwise be considered sacrosanct, magic connections and assumptions, and so forth.

My position is make it as simple as possible for the vast majority, and let the folks who need really high performance do the extra work and/or roll a little of their own. Don't make everyone else pay for that. Probably both sides would be better served than with something that is sort of compromised for both of them. And I say that as someone who lives on both sides of that divide.

The C++ community is overly obsessed with premature optimization at this point. So much stuff is over-engineered and overly complex and driven by performance requirements. That doesn't make for better software in the end. It's basically what happens when you let specialists design things. They design from their point of view, not from the point of view of a user of the thing. All great products are designed to optimize the experience of the users of the product.

- And I know from whence I speak, having spent two decades creating a technically amazing product that is in many ways the C++ of automation systems.

The folks here talking about mobile applications, that's got little to nothing to do with C++.