tag:blogger.com,1999:blog-6950833531562942289.post5841591122287499298..comments2024-03-25T03:36:48.099-07:00Comments on C0DE517E: C++ is premature optimizationDEADC0DEhttp://www.blogger.com/profile/01477408942876127202noreply@blogger.comBlogger13125tag:blogger.com,1999:blog-6950833531562942289.post-46902301600183556622010-08-14T18:08:51.310-07:002010-08-14T18:08:51.310-07:00Objective-C all the way! Yeah!Objective-C all the way! Yeah!Pantherhttps://www.blogger.com/profile/17310328300673121430noreply@blogger.comtag:blogger.com,1999:blog-6950833531562942289.post-11417926930339069062008-08-08T01:31:00.000-07:002008-08-08T01:31:00.000-07:00Nice article. Sometimes I see C/C++ people not car...Nice article. Sometimes I see C/C++ people not caring about optimizing their code, thinking that there is no need because the compiler optimizes or our computers will be too fast in few years. And on the other side people can do <A HREF="http://www.romancortes.com/blog/voxel-head-in-flash/" REL="nofollow">impressive stuff even in Flash</A> (and some things work different in speed in flash than in C and the curious mind or the performance freak will try to find this in any language or hardware he is going to code.<BR/><BR/>Also both premature and algorithm optimizations are essential. Personally I find algorithm optimizations more interesting and sometimes the system optimizations are trivial except if you are generating clever unrolled assembly speedcodes for a C64 or something :)BugoTheCathttps://www.blogger.com/profile/02935085187743095470noreply@blogger.comtag:blogger.com,1999:blog-6950833531562942289.post-45430309219379858632008-06-25T23:06:00.000-07:002008-06-25T23:06:00.000-07:00Angelo, you asked me for a comment. There were so ...Angelo, you asked me for a comment. There were so many points and so many directions in your post that is is hard for me to provide meaningful comments with the little time I have available for blogging-related activities. That said, to comment just on the C++ bit, my stance is that C++ is a complete and utter abomination in so many ways and I would throw it away in a heartbeat if there existed a viable, more modern, complete "language package." Sadly, AFAIK, there is none. There are so many tools, libraries, middleware solutions, infrastructure needs, etc. that plain require C++ (in one way or another) that switching to a language that actually makes sense is not remotely viable from a business perspective (at least not in the game industry).<BR/><BR/>I very much enjoyed your statement that "There are plenty of books on how bad C++ is [...]." I think you very succinctly captured a large portion of what is wrong with C++ in a single sentence.<BR/><BR/>The reason I haven't (yet, at least) ranted about how shit C++ is on my blog is because it would be a bit like concluding that you shouldn't breathe the air because it is so badly polluted. Unfortunately, no matter how much we'd like to avoid the pollution, the reality is that we will have to breathe the C++ air for many many years to come! (Unless some large corporate backer "pulls a Java," except with a language that isn't shit, unlike Java/C++.)<BR/><BR/>Sorry, all the commentary I have time for; take it or leave it!Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-6950833531562942289.post-48324914098739163942008-06-12T09:41:00.000-07:002008-06-12T09:41:00.000-07:00Marcus, you're reply is interesting and I think th...Marcus, you're reply is interesting and I think that many other programmers agree with you, so I want to reply to each of your observations:<BR/><BR/>First of all: "Bad design usually means that (smart) people had no time to refactor." means to me that designs usually _start_ good.<BR/><BR/>Or let me say it in a more correct way: even when your design starts good, eventually over time your code will rot, having no time to refactor is the main reason this rotten code remains in production.<BR/><BR/>Code does evolve. You start with a good design for a given task. Then people ask you to add more stuff, and they quite fit into your design, so you keep adding features to it. Those features are unexpected, no matter how generic your design was, they are unexpected because you did not know about them when you designed the system in the first place (that's why I think you should keep your design simple, not trying to overgeneralize it too much, because that will most of the times only bloat it, it's better to have a code that's easy to extend and modify, that one that tries to anticipate every possible future request). When a critical mass of those new features are added, eventually your design will turn from being optimal to not be optimal anymore and work is needed to evolve it. Quite often, this is not done.<BR/><BR/>Second point: I don't think that languages different than C++ require less design, or are easier to design, so having good designers will always be needed. It will be needed even more if you're not using C++, languages that offer more advanced constructs require better designers in order to use those constructs. C++ is quite simple, in its concepts, and quite arcane in the implementation of those simple concepts!<BR/><BR/>Smarter languages are needed to make our iteration times shorter, they are not magic spells that will turn an ignorant programmer into a great designer.<BR/><BR/>Last but not least, the whole point of the article is that I believe that with the right tools we can be less concerned about some details that we should not care of anyway, be more productive all around, and so be more focused into making our code run faster, first and foremost through better design. So I am as concerned as you about milliseconds (of course I am! I'm an "hardcore" graphics programmer, not a web designer), but I do think that a jump in the quality of our code will be made if we move from looking at the assembly to looking at the design (threads, memory locality, all that stuff that can't be patched into a program just modifying a few functions at the end of the project).DEADC0DEhttps://www.blogger.com/profile/01477408942876127202noreply@blogger.comtag:blogger.com,1999:blog-6950833531562942289.post-34016702954985618462008-06-12T07:34:00.000-07:002008-06-12T07:34:00.000-07:00"Bad design usually means that (smart) people had ..."Bad design usually means that (smart) people had no time to refactor."<BR/><BR/>I can not agree. That implies that any design is bad at the beginning, and it can only be improved untill it becomes "good" through repeated iterations. While it's true that the design needs to be reviewed multiple times during the development, it's also true that skilled software designers are able to make it so that it's resilient to changes, or at least allowing them to be done in a reasonable easy way.<BR/><BR/>No, the problem is that too often "smart people" are really smart at implementing, or at reserching a new lighting model etc., but they are not good designer. That is an activity greatly underestimated by some developers, but it actually requires a lot of experience to be done right.<BR/><BR/>In the end, if your company has the right people doing the right jobs, then using C++ is less painful than the way you are depicting it.<BR/><BR/>Anyway, there are things where C++ is not the most appropriate language to use. Tools are a good example, and I don't see a reason not to use C# or the likes to build them. A videogame, anyway, is still out of range for such a young language, since there are (still) things that requires that extra power C++ grants ... and that is not changing too soon either, because as the platforms (PC, consoles) get better, we developers will always be demanding more power for more awesome effects and stuff, so we will still be struggling to gain back those damn milliseconds.<BR/><BR/>This, at least, in the near future. I think there will be a turning point when the language overhead wouldn't be significative anymore, but I also think it's not that time yet.<BR/><BR/>So, untill then, let's improve our design skills ;) you will see how much that is more beneficial than having the language cover for your lacks.Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-6950833531562942289.post-39071787193345505242008-06-11T19:08:00.000-07:002008-06-11T19:08:00.000-07:00NOTE: of course you will find a lot of (usually ba...NOTE: of course you will find a lot of (usually bad) benchmarks of Java/C#/C++ around that will confirm that in the end, VM stuff can be fast and even faster than staticly compiled stuff.<BR/><BR/>i.e. jttp://www.idiom.com/~zilla/Computer/javaCbenchmark.html)<BR/><BR/>This stuff is so booooooooooring, this is not the point, at all, anyway.DEADC0DEhttps://www.blogger.com/profile/01477408942876127202noreply@blogger.comtag:blogger.com,1999:blog-6950833531562942289.post-80609883534488197142008-06-11T18:54:00.000-07:002008-06-11T18:54:00.000-07:00NOTE: Of course many of the features do have a cos...NOTE: Of course many of the features do have a cost, but isn't that obvious? If we need those features anyway chances are that trying to add them to a language that do not natively support them is going to be worse. And that's true even for C++, we know that RTTI is not so fast, but we know that we pay a cost only when we use it, and that it's still better than most home-made RTTI systems, if we need it (and we do) then it's better to use the one that our C++ compiler provides (generally). Also, compilers will get better and better, this happened for C++, it will happen for C# and for the other languages as well, it's the same story really, we are only at the start of a new cycle.<BR/><BR/>A nice article about the costs of the CLR is this one: http://blogs.msdn.com/ricom/archive/2005/02/22/378335.aspxDEADC0DEhttps://www.blogger.com/profile/01477408942876127202noreply@blogger.comtag:blogger.com,1999:blog-6950833531562942289.post-19733380721773276542008-06-11T00:18:00.000-07:002008-06-11T00:18:00.000-07:00Ah anyway I was pointing at F# and C# as _starting...Ah anyway I was pointing at F# and C# as _starting points_ of our search, not as the final solution.<BR/><BR/>So don't take my post as a C# vs C++ thing. I want to be clear about that. THAT POST IS NOT TALKING ABOUT C#<BR/><BR/>That said, if you want to know my opinion on it, I love C#, it's the only language with a commercial success that has almost everything I always wanted to have (almost, let's say, 70-80% of the things) and I think it's our best bet at the moment for a possible successor to C++.<BR/><BR/>It does fix all C++ design errors (it's a long list, some examples: proper generics, well defined parameter evaluation order, proper enums, it's more type safe, good memory management, better warnings, no #includes, decent compile times, etc etc...).<BR/><BR/>It has some nice syntactic sugar here and there, really well desinged and efficient.<BR/><BR/>It even has some really good language features, like proper first class functions and closures, anonymous methods, type inferencing, the whole LINQ thing... it's a LOT more powerful than Java for example, even if it has everything in a nice and simple C-like syntax, so it seems to be less powerful most of more exotic-to-c-programmers language.<BR/><BR/>It has proper reflection. And that alone is incredibly powerful. It lets you easily do a lot of things in runtime (serialization, inspection of all the objects on the heap, dynamic code loading, code generation, etc...). <BR/><BR/>It makes easy to write tools. Refactoring, code coverage, testing, static analysis, and tons of other stuff. Just have a look at the .Net Reflector and all its plugins!<BR/>I think that the whole "live coding" stuff (I've posted a blog article about that recently) could be done in pure C# in not too many lines of code...<BR/><BR/>To me, it's really close to being "C++ done right".DEADC0DEhttps://www.blogger.com/profile/01477408942876127202noreply@blogger.comtag:blogger.com,1999:blog-6950833531562942289.post-43777340768046967192008-06-11T00:14:00.000-07:002008-06-11T00:14:00.000-07:00"...since bad design usually means bad people, not..."...since bad design usually means bad people, not bad tools..."<BR/><BR/>That's really, really wrong, at least, that's my experience. That really is again what I was trying to explain, it is quite worth another post to make my opinion clear on that.<BR/><BR/>Bad design usually means that (smart) people had no time to refactor. <BR/><BR/>Incredibly skilled programmers happen to do incredibly bad designs, not because they were bad ideas from the start, but because things change, and they did not have the opportunity to change the design as well.<BR/><BR/>Things change, we gather information while we code, requirements change, you know, that's why we don't do monolithic designs but we iterate on code, refactor it, generalize only as needed etc.<BR/><BR/>Iteration is the key to good code. And to fast code as well.<BR/><BR/>Tools DO matter A LOT in making iterations faster, speaking of code, in making refactoring faster.<BR/><BR/>Language design itself can influence how easily we can refactor. Language design can influence how much time each iteration takes. Language design can also influence how easy is to make tools for making those tasks easier (refactoring tools, testing tools, etc etc etc)<BR/><BR/>C# is better than C++ because it has much smaller iteration times, for ALL those reasons.DEADC0DEhttps://www.blogger.com/profile/01477408942876127202noreply@blogger.comtag:blogger.com,1999:blog-6950833531562942289.post-90927055280378845932008-06-10T23:34:00.000-07:002008-06-10T23:34:00.000-07:00But why would C# be more productive than C++ in ga...But why would C# be more productive than C++ in games? I understand it being more productive when you have to do Windows GUI stuff. I understand it being more productive when all you do is piece together libraries, like you do with components in Delphi. But which language features are useful for games? Are we wasting that much productivity with "manual" memory management? How would using C# result in better design?<BR/><BR/>I agree that bad design happens, and that it's the worst kind of performance problem, because the only way out after painting yourself into a corner is a massive rewrite. I just don't see how C# would make a difference there, since bad design usually means bad people, not bad tools.<BR/><BR/>I can see how the exotic stuff (i.e. Haskell, CAML and the likes, not Java and C#) could make a difference, because the code is shorter and more concise. Being shorter, it's easier to modify it and it's easier to understand the system as a whole. However, this has perils of its own, like in the classic Haskell qsort example:<BR/><BR/>qsort [] = []<BR/>qsort (x:xs) = qsort (filter (< x) xs) ++ [x] ++ qsort (filter (>= x) xs)<BR/><BR/>Nice, clean, easy to understand, horribly slow. To do it properly you actually need more code than in C. Granted, this is not the norm, but it's something to look out for if these things go large-scale.Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-6950833531562942289.post-16994551793550040782008-06-10T09:48:00.000-07:002008-06-10T09:48:00.000-07:00I want to make it clear (hopefully)In the end what...I want to make it clear (hopefully)<BR/><BR/>In the end what I'm arguing about is that writing huge projects in C++ is such a waste of time (like it was doing them in C or Assembly years ago) that we can't manage it anymore.<BR/><BR/>And being so expensive is not only a problem for our productivity, but in the end also for the performances, because we don't have anymore the time to think about them.<BR/><BR/>We care, but we don't have the time to care.<BR/><BR/>In every project I've seen things go slow not because programmers are ignorant, but because the "to do" list of possible "optimizations" that should be done and algorithms that could be tried always remains a to do list, never a done one.<BR/><BR/>So let's first try to have again control over our project complexity. Let's try to be productive again, even in a slightly less performing language (even if as I pointed out, most of the C++ alternatives are not slower, maybe now they have slightly slower compilers, but as languages there are no reasons they could not be as fast as C++).<BR/><BR/>The time we gain doing that could be spent again in optimizations. And in the end we might even well outperform our slow-code-in-a-fast-langauge implementations.<BR/><BR/>To Mihnea: I know that "mature" optimizations are fundamental, and that optimizations should not be done last. That's why I'm suggesting, let's be more productive, so we might early on focus on performance, and make our designs performance conscious. As of now, we are using a fast language, so our functions should be reasonably fast, and where they are not, we can use a profiler and optimize them. But our overall designs often are wrong, so having each function to be "fast" is not useful, the underlying idea is wrong, not the implementation.<BR/><BR/>This productivity vs performance tradeoff is not something so heretic to be proposed. Tim Sweeney himself said the same in his POPL talk (http://www.cs.princeton.edu/~dpw/popl/06/Tim-POPL.ppt)<BR/><BR/><< When updating 10,000 objects at 60 FPS, everything is Performance-sensitive. But: Productivity is just as important. Will gladly sacrifice 10% of our performance for 10% higher productivity. We never use assembly language >>DEADC0DEhttps://www.blogger.com/profile/01477408942876127202noreply@blogger.comtag:blogger.com,1999:blog-6950833531562942289.post-85153873280811826242008-06-10T04:24:00.000-07:002008-06-10T04:24:00.000-07:00Again an interesting article that we could argue a...Again an interesting article that we could argue about endlessly.<BR/>As a fanatic C++ supporter I would recommend you to see the lecture that Stroustroup gave at the University of Waterloo or his book on the design and evolution of C++.<BR/>Sure, C# is very convenient, but for me it has a very narrow application domain. Saying that C++ is difficult or complex doesn't really scare me away from that language. The lack of some "power" features in C#, on the other hand, really pisses me off.Unknownhttps://www.blogger.com/profile/00325129436405380404noreply@blogger.comtag:blogger.com,1999:blog-6950833531562942289.post-16910223711538385832008-06-10T00:14:00.000-07:002008-06-10T00:14:00.000-07:00"We laugh if some new language (with a new, and no..."We laugh if some new language (with a new, and not so optimized compiler) reachs only 80% of the performance of optimized C++. But we generally don't write optimized C++. We are way under the 80% of an optimized implementation, in most of our code."<BR/><BR/>Yeah, but the thing is, you're not writing optimized C#/Lisp/Haskell either. And the really bad thing is that it's way easier to destroy performance by thinking in C#. I fear that in practice the gap is larger than 80%.<BR/><BR/>The new-wave languages teach you to look at the machine and the library as a black box. As a result, people who start with them don't understand anything about performance. Ask them to make a piece of code faster and they'll look for algorithmic solutions. Sure, Big-O optimizations come first, but many things follow. If you don't understand the machine and the standard library, you're stuck. Even if you do understand the machine, the new stuff makes it harder to see what's going on and to catch real performance problems that plague many applications, like memory allocation and useless copying.<BR/><BR/>C# is meant to be used in desktop applications where the bottleneck is the disk, network or DB server. Desktop applications are idle most of the time. They wait for user input, do some tiny processing, display the result and then go idle again. Even if the processing involves doing something interesting with the local CPU, 500 extra milliseconds will not matter, as the user will barely feel them. Optimizing this would be a major waste of time, regardless if the problem is algorithmic, memory handling or a slow VM trying to turn alien concepts into real machine code. On the other hand, wasting 500 milliseconds in a game is not going to go unnoticed.<BR/><BR/>Yes, premature optimization is evil. However, late optimization doesn't exist. I see all sorts of success stories about somebody writing a tic-tac-toe game sub-optimally and then optimizing it after getting the important stuff to work. The morale of these stories is always that you should leave optimizations at the end. Cute, but terribly wrong. This doesn't scale. There's no such thing as optimizing a large project at the end by fixing some spikes in the profile. You need to keep performance in mind throughout the project, otherwise it ends up just like you were saying above: nothing in particular is slow, but the whole thing is crawling. Sure, spending one month at the beginning of the project writing an ultra-optimized math library is a waste of time, since this is small and self-contained, so it can be done later if it actually proves to be a bottleneck. However, littering the code with containers that allocate once per element can't be optimized later. Bad ownership design which leads to useless memory copying can be "optimized" at the end by rewriting large parts of the code and there's no time for that, ever.<BR/><BR/>I don't think the new stuff is free of bad practices, especially bad performance practices. It's just that it's not used in high-performance code, so there was no need to come up with a list of things you shouldn't do. Some of the new languages have a prettier syntax than C++, so it's a bit harder to write horrible code, but there are style guides for them too. And, in the end, bugs are equally easy to program in all of them, if you are trying to accomplish the same thing.Anonymousnoreply@blogger.com