Timeline for Is there any reason to use C++ instead of C, Perl, Python, etc.?
Current License: CC BY-SA 2.5
47 events
| when toggle format | what | by | license | comment | |
|---|---|---|---|---|---|
| Sep 5, 2018 at 13:58 | comment | added | Konrad Rudolph | @ThorbjørnRavnAndersen It isn’t always the same: it’s only the same for a given call to the sort method. But if the user calls sort again, even with the same generic types (which are type-erased anyway), they might pass a different comparator. | |
| Sep 5, 2018 at 11:20 | comment | added | Thorbjørn Ravn Andersen | An interesting case for Java where the JIT can inline small function calls. Is it smart enough these days to recognize that the comparator parameter is always the same so it can be inlined? | |
| Nov 2, 2015 at 13:51 | comment | added | Konrad Rudolph | @martinkunev If you don’t think it’s a strong enough reason then you probably work in a domain where that’s true. If, however, you work in a domain where a strong and finely tuned algorithms library is necessary, believe me, this is a good enough reason — I work in bioinformatics, and it’s crucial here. | |
| Nov 2, 2015 at 13:08 | comment | added | martinkunev | More of a philosophical than technical debate. Unless you minimize leaky abstractions, some'll end up causing more problems than they solve. You may save time with C++ std. or you may waste time until you realize you've made a bad decision. Then too much may already depend on your choices. When C++ std doesn't do what you need, you'll have to write (or modify existing) code anyway. Writing a general-purpose fine-tuned sort is indeed really hard. That's a reason to use domain knowledge to tune sorting for what is needed in the project. Anyway, I don't think std is enough of a reason to use C++. | |
| Oct 31, 2015 at 16:37 | comment | added | Konrad Rudolph | @martinkunev I agree with some things you’ve said, except that it simply doesn’t apply here. Every function call obviously represents an abstraction, and leaky abstractions are fundamentally unavoidable. Regarding sort, I’ve encountered situations where the difference was non-negligible, and your suggestion to write your own general-purpose sort function is utterly impractical: writing a fine-tuned sort is really, really hard. You don’t do this. You use a proven implementation. — And yes, std::list is terrible. But the standard library algorithms aren’t. | |
| Oct 30, 2015 at 19:20 | comment | added | martinkunev | Implicit behavior makes the code harder to track and understand. It can also lead to bugs, unexpected behavior, etc. While C++ does a lot for you, this is not always beneficial. It's great to have abstractions but not leaky abstractions (and for performance, abstractions tend to leak). qsort may be slower than std::sort, but not that much slower and it doesn't really matter because often you'll end up writing your own anyway. If we consider standard library problems as drawbacks of the language, then I would mention std::list. | |
| Jan 5, 2015 at 20:44 | comment | added | Rob K | Bjarne Stroustrup examines the efficiency of C qsort() vs. C++ std::sort() in some detail in part 3 of Five Popular Myths about C++. Turns out C++ is going to be quite a bit more efficient. | |
| Apr 22, 2013 at 6:17 | comment | added | yannis | @StereoMatching Tone it down a bit please, this is a Q&A for professional software developers, not really the best place for flame wars and rants. | |
| Apr 20, 2013 at 12:56 | comment | added | StereoMatching | JesperE, for a competence c++ programmer, they know what kind of c++ codes would bring them peformance penalty when compare to c solution.The difference between competence c programmers and competence c++ programmers is like the following post(ttsiodras post it) said, competence c++ programmers know how to write no run-time overhead, more safety and less codes when compare to c programmers, you will never know how could this be done if you don't study c++ carefully.Stop acting like a FUD programmer like linus who criticize c++ without trying to understand c++ | |
| Sep 28, 2012 at 18:23 | comment | added | Konrad Rudolph | @JesperE That is simply not a correct distinction. If those abstractions get in the way, simply don’t use them. But in cases where they can be used efficiently, C++ allows writing simpler code than C would. | |
| Sep 28, 2012 at 18:11 | comment | added | JesperE | C++ does more than just "tips the balance". C is closer to the metal, while C++ provides better abstractions. When you want to squeeze the last cycle out of the hardware, C++ complicates things by hiding many things behind templates and other abstractions. In some cases that may still be beneficial for performance, but in other cases not. | |
| Sep 28, 2012 at 17:50 | comment | added | Konrad Rudolph | @JesperE To some extent. However, the idea here seems to be that C++ requires more understanding to produce equally well-performing code, and I don’t believe that: sure, if you write high-level code without understanding performance implications then chances are this will be slow(er). But all C++ does is tip the balance in favour of efficient abstraction. It doesn’t change the fact that in order to write a given system (whether in C or C++) you need to understand it. To get efficiency in C, you’d write complicated low-level code. | |
| Sep 28, 2012 at 17:45 | comment | added | JesperE | @KonradRudolph Why not? It affects how easy it is to understand what kind of code is going to be executed. Doesn't that matter? | |
| Sep 28, 2012 at 17:15 | comment | added | Konrad Rudolph | @JesperE It’s even easier in assembly. It’s true – but that’s not an argument. | |
| Sep 28, 2012 at 16:20 | comment | added | JesperE | One problem with writing high-performance C++ code as opposed to C (which I don't see anyone mentioning) is that in C it is comparatively easy to get a rough idea of what code the compiler is going to generate. In C++ this is in general very difficult, mainly due to RAII. | |
| Jul 25, 2011 at 12:44 | history | made wiki | Post Made Community Wiki by user32315 | ||
| Jul 11, 2011 at 12:09 | comment | added | Konrad Rudolph | @Jason Indeed, the same that counts for C++ also counts for Ada, D, Ocaml and perhaps a few other oddball languages. | |
| Jul 11, 2011 at 11:17 | comment | added | JasonFruit | What about Ada's generic packages (and other generics) --- I think they're handled at compile-time in a similarly efficient way. | |
| Dec 27, 2010 at 23:27 | comment | added | sbi | @Steve314: What you call "bloat" is what is done manually for C and Java. In C++, it can be automated, and compilers can be as smart as vendors dare to make them to avoid bloat. If I have to decide between either being slow (as in C) or use duplicated code (as in Java), having the compiler doing the duplication (and maybe being smart about it) seems pretty good, no? | |
| Dec 24, 2010 at 8:57 | comment | added | jalf | Of course. It depends on the workload. Show me an implementation strategy that is optimal in all cases. I'm just saying that templates do not automatically imply bloat. It depends on how they're used, and in some workloads, templates might lead to less bloated code than a single general implementation. | |
| Dec 24, 2010 at 4:17 | comment | added | user8709 | @jalf - a lot of data in many of my applications is in database-table-like form - containers of record-like items. Sometimes hundreds of different record-like types, and inner loops generally do work with several tables at once. In short, there are good reasons to believe that I can benefit by using the same underlying code to search/insert/whatever in a container irrespective of the record-type it contains - it very often is already in the cache. I use my own container library in part because it is a thin typesafe wrapper over non-template code, and saved on bloat in the past. | |
| Dec 24, 2010 at 4:11 | comment | added | user8709 | @sbi - template metaprogramming in C++ is ugly and fragile. It is also powerful, but that only overrides the ugliness and fragility in a few special cases. There are some big wins for C++ templates, and sort certainly stands out - but even that can be bloat prone at times. If you sort lots of vectors of basic types you win - but if you sort lots of vectors of different classes you probably lose. Typesafe container classes need a lot of care to avoid bloat. Last I checked, standard container implementations generally don't bother with bloat-avoiding measures. | |
| Dec 23, 2010 at 14:44 | comment | added | jalf | ... because much of the code can be inlined or optimized away. A sort for integers may be able to avoid generating code for a lot of special cases that are only relevant for other types, so while there may be a lot of code paths, each individual code path is certainly not bloated just because you use templates. Often, the opposite is the case. | |
| Dec 23, 2010 at 14:42 | comment | added | jalf | @Jaroslaw: the funny thing about the instruction cache is that it is a cache. That is, it does not try to store everything, only recently used code. Templates might generate lots of similar code for different types (a vector.push_back for vector<int>, and another for vector<float>, but while working with a vector<int>, there is little reason why the vector<float> code would be in the instruction cache. So I don't see how that really matters. Every individual template instantiation is highly optimized and typically more compact than generic catch-all implementations | |
| Dec 23, 2010 at 13:02 | comment | added | Neil G | @konrad, yes, but we're talking about adding a reallocate function to std::allocator. That function could easily invoke the move constructor if necessary. | |
| Dec 23, 2010 at 12:42 | comment | added | Konrad Rudolph | @Neil: the problem is that realloc either reuses the old memory, or returns a new pointer and scraps the old memory. Without calling any destructors, of course. This gives the calling code no chance to call destructors: if it does so before calling realloc, it might destroy memory prematurely. If it does so after calling realloc, then the destructor calls are executed on freed memory => UB. | |
| Dec 23, 2010 at 11:59 | comment | added | Neil G | @mojuba, yes, and why isn't it possible for a reallocate function to call the copy constructor (or move constructor in C++0x)? | |
| Dec 23, 2010 at 11:12 | history | edited | Konrad Rudolph | CC BY-SA 2.5 | added 10 characters in body |
| Dec 23, 2010 at 11:11 | comment | added | sbi | @Steve314: Konrad has explained one very common case where template improve performance. How can you say this isn't usually the case?? Enter template-meta programming, where very complicated code often compiles down to a few machine instructions. If you want to see what TMP can do, have a look at templog.org, which boils down a complex logging statement to nothing (tested on VC, with logging disabled) or one if to check whether a log message should be shown. Show me one other language where syntactic elegance combines with tremendous efficiency in such a great way. | |
| Dec 23, 2010 at 10:20 | comment | added | Konrad Rudolph | @Jaroslaw, @Steve: but the same (= code bloat, instruction cache misses) is true for hand-optimized code which is adapted for each data type (see Java’s various Arrays.sort implementations). Only you lose the advantage of high abstraction. This isn’t a specific disadvantage of templates, it’s a disadvantage of code duplication in general. Furthermore, this tends not to matter since in tight loops, it’s usually always the same code that is loaded. | |
| Dec 23, 2010 at 10:11 | vote | accept | Ehsan | ||
| Dec 23, 2010 at 10:05 | comment | added | mojuba | @Konrad Rudolph: please see my ohter answer above, but actually you may be right regarding garbage collectors: I'm not sure they can handle reallocations of pointers. But then it depends on the GC. Some very simple ref-counted GC's can do fine (PHP comes to mind). | |
| Dec 23, 2010 at 9:59 | comment | added | mojuba | @Neil G: unfortunately it's not only POD vs non-POD. The problem is that in C++ a vector element can contain pointers to locations that potentially may be affected by realloc(). The only way of keeping these pointers up to date is copying elements (during resizing of a vector), and calling copy ctors. There is no way in C++ for the vector implementation to know if a vector element in fact contains such pointers or not. | |
| Dec 23, 2010 at 8:36 | comment | added | user8709 | Templates can be prone to bloat, which is a big run-time cost. It's not just that the program takes longer to load, but also that a smaller proportion fits into the highest cache levels at any one time. A well written template may be a typesafe thin wrapper around non-typesafe underlying code, but then you re-introduce more obvious abstraction overheads. Templates are worthwhile primarily for type safety reasons - not high-performance abstraction reasons - though there are exceptions to that. | |
| Dec 23, 2010 at 3:55 | comment | added | Neil G | @Charles, Yes, good point. In fact, that's a much better solution. reallocate could use C++0x's move semantics in the case that the type is non-POD and the new block is in a different place. | |
| Dec 23, 2010 at 0:18 | comment | added | Charles Salvia | @Neil G, but that would require a change to std::allocator. It would need a reallocate function that container classes can take advantage of. | |
| Dec 22, 2010 at 23:39 | comment | added | Neil G | @mojuba, I'm not sure, but I think C++0x will be able to address mojuba's concern. I think I read that is_pod will be available, and in the case of a POD type, you could use realloc safely. | |
| Dec 22, 2010 at 23:26 | comment | added | jsz | > "C++, on the other hand, offers an indirection mechanism that incurs no (performance) cost: templates." obviously you haven't heard of the instruction cache. | |
| Dec 22, 2010 at 21:55 | comment | added | aneccodeal | upvoted, though I would suggest that Ocaml is an example of a language that can get very close to C++ performance while still allowing highlevel abstractions (though these are generally different abstractions from those available in C++ - things like function composition, functors, etc.) as well as well as niceties like type inference, garbage collection and even stronger type safety than what's available in C++. | |
| Dec 22, 2010 at 21:07 | comment | added | Konrad Rudolph | @mojuba: they can’t because of destructors. Apart from that, please tell me which higher-level languages do use realloc. I don’t know of any that do. I know that most don’t – but then, comparing with managed memory is always difficult. A custom allocator can in fact help, though a custom allocator cannot take advantage of realloc either. What it can do, though, is emulate realloc on a higher level. In that way, they can achieve a very similar behaviour to garbage collected storage (if that’s what you were referring to). | |
| Dec 22, 2010 at 21:04 | comment | added | Konrad Rudolph | @Manuel: that’s indeed a nifty trick but this optimization (applied to function pointer inlining) is highly complex (it basically requires a flow analysis to show that the pointer never changes) and cannot in general be relied on. I’d be interested in numbers, though. Do you have any? | |
| Dec 22, 2010 at 20:55 | comment | added | mojuba | no performance overhead at runtime - that's not always true. If you look at STL vector implementations you will see that they don't take the advantage of using realloc() (they can't because of pointers, long story) whereas all higher-level languages that I know can and do use realloc() in vector impl's. This is just one example that it's not that obvious and all black-and-white. | |
| Dec 22, 2010 at 20:52 | comment | added | Nils | I wonder about Exceptions, do they come with overhead? | |
| Dec 22, 2010 at 19:38 | comment | added | Manuel | Actually, modern compilers such as MSVC are capable of the nifty trick of cross-module inlining. | |
| Dec 22, 2010 at 17:51 | comment | added | Chris | I do now know enough about C++ to know whether you are spot on or wrong. But also want to add you only received 1 downvote so relax. This is the internet and downvotes happen. Great answer though if its technically sound! | |
| Dec 22, 2010 at 14:52 | history | edited | Konrad Rudolph | CC BY-SA 2.5 | added 310 characters in body |
| Dec 22, 2010 at 14:47 | history | answered | Konrad Rudolph | CC BY-SA 2.5 |