3 ms·
Yeah you probably DO understand std::vector which is what I said. You probably don't understand std::list and std::deque forget std::rope std::map std::unorder
by harry8 12y ago
Yeah you probably DO understand std::vector which is what I said.
You probably don't understand std::list and std::deque forget std::rope std::map std::unorderd_map, std::set etc. etc.
I know I don't. I know what they do, I know how they're probably implemented. I know their big O characteristics etc. But they're optimised for high level generality not for the thing I'm doing on the hardware I'm targeting. I don't know how they perform on particular hardware, how cache sizes affect them etc etc etc. You have to find that out for yourself, hopefully by benchmarking before you use them, rather than finding out they suck very, very hard in production.
Bjarne Stroustrup himself as chief c++ booster says: "Everybody gets this wrong" when comparing something as simple as std::vector to std::list in performance.
"Everybody gets this wrong" --Bjarne Stroustrup
Maybe you're smarter than the rest of us, it's entirely possible but the rest of us use this language and that's what I'm talking about here. Eh see for yourself.
https://www.youtube.com/watch?v=YQs6IC-vgmo https://www.youtube.com/watch?v=YQs6IC-vgmo
Note that the benchmark he shows is not available, and it's not available in the STL. It might perform completely different on your embedded project. Eh so you have to write this benchmark (and all the others you might need) yourself. Write it every time you need to use an STL container that isn't vector and you care before you have the evidence you need to reject it. Seriously. WTF is up with that?
You have to care? Write your datatructure and algo yourself, you can reason about how the memory is used, how the caching performs. How the compiler vectorises, inlines it. You have an idea of the assembly language that will be generated (or at least you should). If you look at an STL implementation you feel your eyes bleed. It's ridiculous, what instructions will the compiler produce, hell what c++ code will it even compile?
But if you dont' care it's fine - and there are great reasons not to care. Being in a situation where you don't have to care is awesome, use them. Eg setup code that can be slow before you get the the stuff that has to be fast.
I have never seen an exception safe C++ codebase, I don't believe such a beast exists. Even if it does it's a properly hard problem that you can't keep in check with multiple committers. Just see how much time Herb Sutter and Alexandrescou (who has now dumped c++ as needing to become a legacy language) put into trying to explain how to do it. And failing to do so. The idea "exception safe" in c++ easy is only entertained by those who don't understand the problem. Scope guard is not a magic bullet. How does the silly contrived example of opening a file work with multiple threads? Look at his example, push_back of a pointer onto a vector. I've never seen anything other than
vec.push_back(ptr); //get on with life
in the wild. But hey, maybe I'm missed some and it's only 99% of c++ code that is by the Alexandrecou definition "exception unsafe" Maybe 99% of c++ programmers aren't smart enough to program in the language?
If you use C or C++ and genuinely don't care about performance you performed a premature optimisation in the choice of these languages. Any JVM language would be suit your needs better in some way. Haskell might, python, ruby, scheme might.
The whole point of C and C++ is being able to get that really low level performance.
Yes totally, I DO recommend "monkeying with text generation" because you won't do it unless you actually need to. Templates have the opposite characteristic, sadly.
(And just quietly, to hell with the bozo who voted me down to 0 for participating in this discussion, you're not very bright, responding as maxlybbert did is the correct thing to do if you disagree, disagreement is what this whole thing is all about otherwise why bother?)
- maxlybbert 12y ago> You probably don't understand std::list and std::deque forget std::rope std::map std::unorderd_map, std::set etc. etc. These were our general interview questions at the last place I worked (until we moved almost completely to Javascript development). Understanding big O performance characteristics is a very important skill, I don't consider it optional; at least in the world of C++ development. We asked about them because they use different, well-known, algorithms to get various results and we wanted to know if people had the skill to figure out appropriate trade offs when solving a problem. Minor quibble: unless something has changed, rope ( https://www.sgi.com/tech/stl/Rope.html https://www.sgi.com/tech/stl/Rope.html ) isn't in the Standard ( http://en.cppreference.com/w/cpp/container http://en.cppreference.com/w/cpp/container ). > I know what they do, I know how they're probably implemented. I know their big O characteristics etc. Then iterator invalidity should be easy to figure out for each of the containers. You don't even need a table. > But they're optimised for high level generality not for the thing I'm doing on the hardware I'm targeting. They're designed to be as efficient as they can be while also being general, yes. > I don't know how they perform on particular hardware, how cache sizes affect them etc etc etc. That's hardly a surprise, and that knowledge will go stale pretty quickly. Which is why Stroustrup says everybody gets it wrong. Many programmers have no idea how badly cache hostility will hurt them. > You have to find that out for yourself, hopefully by benchmarking before you use them, rather than finding out they suck very, very hard in production. I don't see how it could be different. Again, hardware architecture changes over time. > Note that the benchmark he shows is not available, and it's not available in the STL. I think you're looking for something like http://www.stepanovpapers.com/container_benchmark.cpp http://www.stepanovpapers.com/container_benchmark.cpp . I can imagine a compiler vendor or library vendor shipping something like this, but I wouldn't expect it to be in the STL. https://github.com/rjernst/stepanov-components-course/tree/master/code/lecture1 https://github.com/rjernst/stepanov-components-course/tree/m... is also useful. > Seriously. WTF is up with that? I believe the first programming textbook I read mentioned the use of a profiler. If you're trying to improve performance, it's probably better to start with a profiler than with benchmarks. Then again, Douglas Crockford mentions how silly it is for programmers to make every choice based on performance instead of things like maintainability. Only worry about performance if you know it actually matters (and a profiler can help you decide if it matters). > I have never seen an exception safe C++ codebase, I don't believe such a beast exists. We may be talking about different things. I've worked on moderate sized code bases that wouldn't leak memory or leave files open, etc. if exceptions were thrown (and used ScopeGuard to do that), but our error handling code was as simple as possible. We had a large loop processing requests, and we'd throw out the request if there was any exception. We followed what Anders Hejlsberg describes as the expected C# pattern ( http://www.artima.com/intv/handcuffs.html http://www.artima.com/intv/handcuffs.html ): "Surely in any kind of event-driven application like any kind of modern UI, you typically put an exception handler around your main message pump, and you just handle exceptions as they fall out that way. But you make sure you protect yourself all the way out by deallocating any resources you've grabbed, and so forth. You clean up after yourself, so you're always in a consistent state. You don't want a program where in 100 different places you handle exceptions and pop up error dialogs. What if you want to change the way you put up that dialog box? That's just terrible. The exception handling should be centralized, and you should just protect yourself as the exceptions propagate out to the handler." But using C++ meant we didn't have to try to get the try ... finally's right ( http://mail.openjdk.java.net/pipermail/coin-dev/2009-February/000011.html http://mail.openjdk.java.net/pipermail/coin-dev/2009-Februar... , for the record, they accepted the proposal). > How does the silly contrived example of opening a file work with multiple threads? There isn't enough detail to answer this question. Are the threads going to share a single std::fstream? Or do they each get their own? Do we have access to some kind of file locking mechanism? Clearly there are solutions to the problem. I have databases running on my system that were written in C and C++ and they manage to manipulate files from multiple threads. > Look at his example, push_back of a pointer onto a vector. Is the vector responsible for cleaning up the pointer? Will the pointer outlive the vector? Can you use shared_ptr? There are three, simple, answers to the question (std::vector<T*> if the pointer will outlive the vector and something else promises to clean up; std::vector<std::unique_ptr<T>> if the vector takes over responsibility to clean up; and std::vector<shared_ptr<T>> if the responsibility has to be shared). You don't need ScopeGuard for any of those cases. vec.push_back(ptr) will do the right thing for raw pointers (if cleanup is guaranteed elsewhere) and shared_ptrs (i.e., if "ptr" is a shared_ptr<T>), while vec.push_back(std::move(ptr)) will do the right thing for a std::vector<std::unique_ptr>> (if "ptr" is a unique_ptr<T>). In fact, vec.push_back(std::unique_ptr<T>(new T(...))) will also do the right thing for a std::vector<std::unique_ptr<T>>. > maybe I'm missed some and it's only 99% of c++ code that is by the Alexandrecou definition "exception unsafe" Not all code has to be exception safe (e.g., if the policy is to abort an any exception, or if memory leaks are deemed acceptable). And Google, somewhat famously bans them ( http://google-styleguide.googlecode.com/svn/trunk/cppguide.html#Exceptions http://google-styleguide.googlecode.com/svn/trunk/cppguide.h... ). But the numbers are better than you believe. Mozilla seems to do a decent job with exception safety. The biggest source of exception unsafe code appears to be programmers who believe everything must be allocated with new in all cases. > If you use C or C++ and genuinely don't care about performance you performed a premature optimisation in the choice of these languages. Any JVM language would be suit your needs better in some way. That is a surprising statement, especially since you don't necessarily have any idea what my needs are. There are times that I choose to write code in C# or Perl (never Java, but that's my personal preference), so I don't use C or C++ if it doesn't make sense. But there are times that I choose C++ for reasons other than performance. It can actually be a good fit for what I'm doing (e.g., I don't like using neutered generics when I really need templates, and I don't like putting things into classes if there's no need to ( https://news.ycombinator.com/item?id=3717715 https://news.ycombinator.com/item?id=3717715 )). Or (more often) I know a C++ library that's a great fit and that doesn't exist in C# or Perl.