Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Pop Quiz: Why should I clutter my brain with these little guessing games about what the compiler is doing? And why should these pop quizzes slow down my group's code reviews? There are, after all, languages out there that do not force this insanity on us.

The alternative for performance-critical applications is not Java, but C. C remains surprisingly tough competition after all these years for those rare pieces of software where programmer time is cheap compared to hardware resources. Having had non-trivial experience of both languages, reasoning about the performance of a C program is much, much easier than reasoning about non-trivial C++ programs' performance. Guesses based on local code inspection have an order of magnitude less uncertainty attached to them, which is basically what Rachel is saying here.



I am surprised to see that so many programmers still like to reason and guess what the performance of their program is instead of profiling it...

And hearing C proposed as an alternative to C++ is mind boggling. I don't want to match malloc/free calls, strcat strings together or realloc pointers. I don't want to declare a bunch o function pointers in a struct and call it OOP. I don't want to use macros because C99 has poor adoption rate and C89 doesn't have inline. I don't want to watch the compiler blissfully convert unrelated types to one another just because it can. I don't want to pass types around as void* and lose any useful type information I might have had. I don't want to fumble with return codes.

And in C++ I don't have to. I can use Qt, the STL and Boost and be very productive. Telling me to program in C is not even funny.


I propose a lower level than C++ for the kernel, and a higher level for the rest.

C++ is simply at the wrong abstraction level.

Oh, and I don't want to manually track resources myself, either. But guess what, somebody has to do. And on a game console, that's you. There's not much of an OS to speak of.

You did notice I was talking about game development, right? ;)


My reply was not targeted at you and I don't do game programming.

Anyway:

* smart pointers don't need an OS.

* for me, C++ is at the exactly right abstraction level to allow me to use only C++ instead of "C++ + other language" or "other language and C for speed". Most C + HLL proponents underestimate the logistics overhead of using multiple programming languages.


_Most C + HLL proponents underestimate the logistics overhead of using multiple programming languages._

I'll concede that as a valid concern, especially for smaller projects where everybody touches many areas of the code. As projects grow, a separation becomes easier.

Add to that the fact that most games need scripting support anyways, and you'll see that the logistics overhead is at least not much different.


As somebody who's given you a hard time up thread, and who has advocated the C + HLL approach, let me say: you're right, I now think that approach is naive. It's really difficult to share data across the C/HLL boundary, and in normal applications the data representation is the most likely place to need performance tweaking, and thus you often want to represent it in "LLL" data structures.

The mappings of C/C++'s type system into an HLL is almost intractable. What if there's a union somewhere? You could have distinct HLL and LLL representations, sync'ed either lazily or eagerly, but that's really, really complicated.

Unfortunately, you can only apply "C* + HLL" when there's a nice, clear, never-shifting boundary between the HLL and LLL parts. So, language selection is not a false dichotomy; you really do have to choose "mostly one."

(edit: typo, non-sense sentence. Sorry folks, running a fever.)


I've experienced the effects of trying to have the C++ "kernel" and a HLL for the "rest" on a project.

We allowed large parts AI/gameplay (not generally what I would think of as "kernel") to be pushed out of C++ into a HLL, and it was extremely painful bringing it back when the performance began to hurt us.


You can't by any chance share a bit more about the project, can you?

I'd certainly be interested to hear about this, because I'd love to know what the breaking points were.


> I am surprised to see that so many programmers still like to reason and guess what the performance of their program is instead of profiling it...

Yeah, us old fuddy-duddies. We also like to reason about the correctness of our code while we're constructing it, instead of writing all of it and testing it. Crazy, huh? Like deep correctness, a performant system does not come from sprinkling some tools over at the end; it's an emergent property of attention to detail at every step.

The performance problems a profiler can show you are the easy ones. Hard performance problems come from users, where you can't touch, feel, and measure the code's dynamic behavior. Somewhere out there, in some customers' hands, software you barely remember writing three years ago is crawling along, and the customer is too livid to clearly express what she's doing to make it slow.

Just like debugging a tough correctness bug from the field, you are stuck alternating between deduction and induction. You try to piece together what the user did, and with luck you can reconstruct the bug! Yay, profile it, deduction worked! But I was almost never this lucky. I was left stuck using my bottom-up understanding of what the source code does and how it could have interacted with the user's setup. Identify a possible critical path for this workload, and stare at that motha with a critical eye: "I think you're slow sometimes. But obviously not always. Why? What could make you slow?"

C++ makes this part much, much harder, because even having narrowed it down to a candidate critical path, you can't look at the source code to know (as reliably and quickly as with C) what the hardware is going to do. Notice the qualifiers there (as reliably, as quickly). I'm sure a C++ expert like yourself could rattle off the whole flying circus of default constructors, copy constructors, operator overloads, and destructors that the compiler spits out, but to do so you will need non-local information in a way that you do not for C.

If these problems don't arise in your practice, awesome, good for you. Your marginal user doesn't consider performance problems bugs. That's a great situation to be in, because it lets you focus on features. But it does lead to question of why you are using C++.

> I don't want to match malloc/free calls, strcat strings together or realloc pointers.

If you don't occasionally really need realloc, that's cool, nothing wrong with that, but what kind of resource-intensive software are we talking about, then? It's an important tool in the toolbox when trying to implement data structures that occupy significant fractions of your address space.


Ugh. Try attacking the vector math required for most games programming these days in C, using macros and magic instead of classes and templates and operator overloading. I'd rather blow my own leg off with a bit of C++ any day.


"Guesses based on local code inspection have an order of magnitude less uncertainty attached to them"

...which is why we have profiling tools that make it easy to detect performance hotspots. For the other 95% of our code, the expressiveness of C++ makes it easier to do more work in fewer lines. This is a far more important metric to any working developer (and it's a big reason why languages like Python and Ruby are popular.)

Also, you're exaggerating. I wrote C++ for well over a decade, and I wrote in C before that, and used it again in graduate school for my research. While I can count on one hand the number of times that I was affected by "hidden" C++ costs, I was routinely blindsided by bad C code, where pointer errors, type safety gotchas, and inefficiency due to aliasing are de rigeur. You'd be crazy to write a non-trivial application in C today that wasn't an operating system.


Given that games more or less have to implement their own OS, I hope I'm not completely crazy yet ;)

I am not talking about "business apps" (whatever that is). I'm talking about down-to-the-metal resource management, task scheduling, etc.

I could probably live with those issues in the higher logic layers (although I'd argue a scripting language would make you much more efficient there). But the underlying "OS" as well as computationally intensive tasks do not benefit from C++ that much, and it causes a lot of collateral damage.


" But the underlying "OS" as well as computationally intensive tasks do not benefit from C++ that much, and it causes a lot of collateral damage."

No. C++ has some pretty huge advantages for performance-critical software. Generic programming makes it possible to write extremely succinct, high-performance code. Operator overloading allows the creation of vector and matrix libraries that look like real mathematical expressions, while evaluating to code that's as fast as anything you'll get from Fortran.

I didn't write "business apps" (not sure where you got that). I wrote software that simulated proteins -- in other words, high-performance computing -- and except for FORTRAN, C++ was the best choice for the job. Doing the equivalent optimizations of a library like Boost::MPL in C is a nightmare of pointer arithmetic.

When you throw in the fact that C++ makes it easy to avoid the memory leak, corruption and type safety issues that plague C code, you can easily see why C++ is becoming the language of choice in the HPC world.


_why C++ is becoming the language of choice in the HPC world._

And yet, the HPC world looks for a new language: http://www.cs.sandia.gov/Conferences/SOS10/presentations/Tue...

And a lot of the HPC world still writes FORTRAN or C. (I.e. BLAS, LAPACK, et.al.)

But then again, I don't spend that much time in the true HPC world. Maybe I'm missing a trend there. But from the outside, it looks like C++ is not quite what people wanted.


The HPC world writes a lot of code in FORTRAN because of the library support, and the fact that there's a ton of legacy FORTRAN code that's genuinely hard to rewrite. There isn't much C work going on; the few C libraries that exist are usually wrappers around FORTRAN code.


Profiling tools are post-mortem, and often not able to be enabled in production. What about when the code is not yet running, and you're trying to reason about it as you write it? What about when the performance problem is workload dependent, and only emerges in production, and you need to reason inductively from the source code about what could be going wrong?




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: