4 ms·
The C++ code here is exactly the kind of thing that game developers complain about when they say C++ encourages inefficiency. Calling Haskell fast because it me
by Veedrac 9y ago
The C++ code here is exactly the kind of thing that game developers complain about when they say C++ encourages inefficiency. Calling Haskell fast because it merely draws with that doesn't really make sense in this context. Yes, it's as fast as C++ code that doesn't care in the slightest about efficiency, but people use C++ for the times when they do.
E: As some quick examples, peeking an istream in a loop is extremely inefficient[1], yet is done pervasively. The Derivation type has a bunch of separately allocated strings, and a lot of types like std::map<string, DerivationOutput> are pointer filled. To check whether a string starts with "r:", they allocate a _new string_ and compare it, rather than just doing a normal string comparison.
[1] https://godbolt.org/g/27o9od https://godbolt.org/g/27o9od
- Gabriel439 9y agoWhat is the reason that `peek` is inefficient? Is it just because it is a function call that is not inlined or is there another reason?
- Veedrac 9y agoReally it's the other way around: peek is complex so the compiler didn't inline it. In essence, you do a virtual call which I think winds you up in https://github.com/gcc-mirror/gcc/blob/1cb6c2eb3b8361d850be8e8270c597270a1a7967/libstdc%2B%2B-v3/include/bits/istream.tcc#L620 https://github.com/gcc-mirror/gcc/blob/1cb6c2eb3b8361d850be8... which itself redirects to a whole bunch of stuff. The virtual call alone is a lot more expensive than a simple pointer dereference, and though it's possible proper inlining might have alleviated some of this problem, you're not particularly likely to see it come close to something that's efficient by design.
- tjalfi 9y agoiostream generally has poor performance[0]. TR 18015[1] (Technical Report on C++ Performance) lists some of the implementation challenges. [0] https://stackoverflow.com/questions/4340396/does-the-c-standard-mandate-poor-performance-for-iostreams-or-am-i-just-deali https://stackoverflow.com/questions/4340396/does-the-c-stand... [1] http://www.open-std.org/jtc1/sc22/wg21/docs/TR18015.pdf http://www.open-std.org/jtc1/sc22/wg21/docs/TR18015.pdf
- kazinator 9y ago> but people use C++ for the times when they do. Nope; people use C++ for all the times ... when what they know best is C++. Which is all the time for a lot of C++ developers, I suspect. Then, for a whole bunch of other times not covered by that case, they choose C++ because of tooling and surrounding code into which that code must integrate. If you need a parser, and it has to integrate into a C++ program, you probably choose C++ for that reason, and then write the parser in whatever way you are able while trying to keep it understandable and maintainable, which may not be the most efficient approach. You do that even if you can write the parser in six other languages. The idea that C++ is always selected for speed and used accordingly rings fallacious to me. It's not even the way it should be; choosing the ideal language (and ideal way of using that language) for every little subtask in a large project is going to be harmfully counterproductive. Unless the language count can be kept to no more than two or three.
- Veedrac 9y agoI think this is more a matter of me expressing myself poorly than a real disagreement; we seem to be saying the same thing. What I meant is more that the initial choice of C++ tends to come from a requirement somewhere in the program for the low-level control that C++ needs, rather than the whole thing, and making an argument that Haskell is performant enough to replace C++ only makes sense if it's either fast enough for that case too, or you're willing to have a heterogenous codebase and you don't really care about Haskell's performance anyway.
- kazinator 9y ago> that the initial choice of C++ tends to come from a requirement somewhere in the program for the low-level control that C++ needs Even that doesn't always come from such a requirement. Maybe it's just, "the common denominator of expertise on this team is C++ so we will use that". That original requirement for low-level control is now 5% of the code base, 95% of which is still C++ because of the effect that it's easier to just add more C++ than to balkanize the project with new languages. The parser adds 1%, and scans a config file only about every 100 days days when the C++ server is restarted; why would it have to be fast ...
- pjmlp 9y agoGame developers always need to be dragged by platform owners to adopt modern concepts and programming languages. I am old enough to have heard the same complaint, but with Assembly, C and Turbo Pascals as protagonists. One should program in idiomatic productive code and only if the profiler shows there is a bottleneck, that is actually relevant for the use case at hand, one should bother to spend time optimizing. To add my voice to the other comments, there are many reasons we get to use C++, not only for bleeding edge performance. Portable code across mobile OSes, access to the JVM and CLR monitoring APIs, UWP APIs not exposed to .NET, medical devices DLL and COM libraries are just a few examples that come to my mind.
- Veedrac 9y agoI'm not sure why I'm struggling to express myself here. I'm not saying Nix was wrong not to focus on optimising this; it's not likely to be their bottleneck. I'm saying that the article's argument doesn't hold. Consider a case where somebody is using C++ for mobile OS portability or to hook into another large project, rather than the performance it offers. In that case, the argument that the parser would be equally fast in Haskell is irrelevant because that was never the use-case. Consider a case where somebody is using C++ for performance. In that case, the argument that the parser would be equally fast in Haskell is irrelevant because that's not the part that needs to be fast. The only time "X in Haskell is equally fast to X in C++" is an argument that you care about is when you care about the performance of X, and in that case the code wouldn't look like this.