Slashdot Mirror


Optimizations - Programmer vs. Compiler?

Saravana Kannan asks: "I have been coding in C for a while (10 yrs or so) and tend to use short code snippets. As a simple example, take 'if (!ptr)' instead of 'if (ptr==NULL)'. The reason someone might use the former code snippet is because they believe it would result in smaller machine code if the compiler does not do optimizations or is not smart enough to optimize the particular code snippet. IMHO the latter code snippet is clearer than the former, and I would use it in my code if I know for sure that the compiler will optimize it and produce machine code equivalent to the former code snippet. The previous example was easy. What about code that is more complex? Now that compilers have matured over years and have had many improvements, I ask the Slashdot crowd, what they believe the compiler can be trusted to optimize and what must be hand optimized?" "How would your answer differ (in terms of the level of trust on the compiler) if I'm talking about compilers for Desktops vs. Embedded systems? Compilers for which of the following platforms do you think is more optimized at present - Desktops (because is more commonly used) or Embedded systems (because of need for maximum optimization)? Would be better if you could stick to free (as in beer) and Open Source compilers. Give examples of code optimizations that you think the compiler can/can't be trusted to do."

1,422 comments

  1. Ask the compiler... by inertia187 · · Score: 5, Funny

    Programmer: Hey, compiler. How do you like optimizing?
    Compiler: Optimizing? Optimizing? Don't talk to me about optimizing. Here I am, brain the size of a planet, and they've got me optimizing inane snippets of code. Just when you think code couldn't possibly get any worse, it suddenly does. Oh look, a null pointer. I suppose you'll want to see the assembly now. Do you want me to go into an infinite loop or throw an exception right where I'm standing?
    Programmer: Yeah, just show me the stack trace, won't you compiler?

    --
    A programmer is a machine for converting coffee into code.
    1. Re:Ask the compiler... by Anonymous Coward · · Score: 0

      That's funny?

    2. Re:Ask the compiler... by storm916 · · Score: 1

      Only if if is compiler number 42...

    3. Re:Ask the compiler... by wizbit · · Score: 2, Insightful

      Or a paranoid, depressed android.

    4. Re:Ask the compiler... by llamalicious · · Score: 5, Funny

      And then the compiler shared his view of the universe with the programmer, who promptly committed suicide.

    5. Re:Ask the compiler... by zephc · · Score: 1, Informative

      maybe use 'gcc -S sample.c' (is that the right option? dont have GCC in front of me) where sample.c is a short program with the !ptr and have another file where u use ptr==NULL and see which produces tighter code. Unless optimizations occur *afterwards*, in which case discard this message :-)

      --
      "I would say that 99 per cent of what my father has written about his own life is false." - L. Ron Hubbard Jr.
    6. Re:Ask the compiler... by Anonymous Coward · · Score: 0

      Sort of. You ask the profiler. First you write the code as clear as you can. Then you ask the profiler about places where optimization is worth it. Then you come up with optimizations. Then you profile both versions, use the faster and keep the clearer in the documentation (with version information!).

    7. Re:Ask the compiler... by saden1 · · Score: 2, Funny

      HG2G has got to be the best book on the planet. Here is my favorite dialog in the book.

      --

      -----
      One is born into aristocracy, but mediocrity can only be achieved through hard work.
    8. Re:Ask the compiler... by pboulang · · Score: 2, Insightful

      Tighter code? is that how you are defining optimized? Hmmm... I beg to differ.

      --

      This comment is guaranteed*

      *not guaranteed

    9. Re:Ask the compiler... by fmobus · · Score: 1

      You missed the point The previous example was easy. What about code that is more complex?

    10. Re:Ask the compiler... by Prof.Phreak · · Score: 1
      You also need to run -O2 (or -O3). gcc is pretty lame without optimization turned on. ie, try something like this:
      int gcd(int x,int y){
      if(y == 0)
      return x;
      return gcd(y,x % y);
      }
      With gcc -S , and gcc -S -O3... one will be recursive, the other one will be a loop.
      --

      "If anything can go wrong, it will." - Murphy

    11. Re:Ask the compiler... by bonniot · · Score: 2, Informative
      Oh look, a null pointer... Do you want me to go into an infinite loop or throw an exception right where I'm standing?

      What about using a language where null pointer errors are caught at compile time? Oh, I guess our compiler must have a brain the size of a whole solar system to be able to do that.

    12. Re:Ask the compiler... by Anonymous Coward · · Score: 0

      holy crap. thatis the funniest thing ive read all day. i can now die. holy crap.

    13. Re:Ask the compiler... by Impy+the+Impiuos+Imp · · Score: 2, Interesting

      That's not possible, but a language that doesn't use pointers per se could, and do, exist. Of course they really use pointers behind the scenes, complete with integrity, i.e. NULL checks, so you're not gaining anything.

      Now a processor that zero-checked a pointer on memory deference, auto-built to skip the deference, combined with a language that supported it, would have the check in hardware... ...although zero check is one of the simplest ALU operations, and thus the same speed anyway. Nevermind.

      --
      (-1: Post disagrees with my already-settled worldview) is not a valid mod option.
    14. Re:Ask the compiler... by edf825 · · Score: 3, Funny

      http://www.in.com.au/missing.html ...I just had to post that :)

    15. Re:Ask the compiler... by bonniot · · Score: 2, Informative

      Did you check the links? I'm actually pointing to a specific language where null pointer (OK, references) errors at caught at compile time. It *is* possible.

    16. Re:Ask the compiler... by Anonymous Coward · · Score: 0

      Please go back to Fark and shut the fuck up.

    17. Re:Ask the compiler... by Darren+Winsper · · Score: 1

      No, it catches the condition where a variable *may* be null. It can't tell if a variable is going to be null or not.

    18. Re:Ask the compiler... by bonniot · · Score: 2, Informative

      Correct. Although ideally, if it tells you the variable may be null, then there exists some situation where the variable *will* be null. So you better handle this case. Clearly, the problem of reporting an issue exactly in the cases where it will happen is undecidable, so a safe compiler has to be a bit restrictive. In practice, it seems that most cases where it reports a spurious problem is when it depends on the way clients call your code. And in that case, even if it cannot happen now, it could later happen because of a client change, so it's a good idea to handle that case now anyway.

    19. Re:Ask the compiler... by Anonymous Coward · · Score: 0

      Here's my question on all this mess.

      Say you have a very long select/case type of statement, perhaps its some sort of interpretter or whatever. Anyway, its my understanding that the code generated would be about the same as a string of if/else statements where you test each condition linearly.

      However, if you don't use select/case, and actually use if/else statements, you can do a non-linear search. Does a compiler ever generate a binary search tree for a large select/case ?

      crcthought@yahoo.com

  2. Security by Anonymous Coward · · Score: 0, Interesting
    The future's pretty clear.

    You MUST trust the compiler more and more to protect the code from buffer overflows and other trivial, but hard-for-humans-to-detect mistakes.

  3. Clear Code by elysian1 · · Score: 5, Insightful

    I think writing clear and easy to understand code is more important in the long run, especially if other people will have to look at it.

    1. Re:Clear Code by normal_guy · · Score: 5, Insightful

      That should be "especially _since_ other people will have to look at it."

      --

      Linux: Free if your time is worthless.
    2. Re:Clear Code by Anonymous Coward · · Score: 0
      if other people will have to look at it

      Why would you? There's always going to be a highly specialized, small team working on a particular piece of code. Unless, of course, you're talking about OSS.

    3. Re:Clear Code by daveho · · Score: 5, Insightful

      I agree 100%. Write code that is easy to understand and modify, then optimize it, but only after you have profiled it to find out where optimization will actually matter .

    4. Re:Clear Code by amembleton · · Score: 1

      Parent is correct, although on some embedded systems it may be more important to have compact and efficient code but the compiler should do this.

      I probably spend at least twice as long trying to understand what old (mostly uncommented) code currently does than actually fixing it.

    5. Re:Clear Code by Anonymous Coward · · Score: 1, Insightful

      Other people don't have to have a look at it if it works. If it doesn't work, you've better write new code to replace it. Modifying legacy code is always a security risk.

    6. Re:Clear Code by glimmy · · Score: 1

      I agree since saving hours of guessing what something will do should outway the extra time it takes to run it

    7. Re:Clear Code by Lord+Kano · · Score: 1

      In 99.99% of all applications, I totally agree with you. Unless we're talking about specific embedded systems where the number of spare cycles is at a premium, go for the more readable code.

      LK

      --
      "Hi. This is my friend, Jack Shit, and you don't know him." - Lord Kano
    8. Re:Clear Code by Tr0mBoNe- · · Score: 2, Interesting

      I agree. I write my code under the assumption (rightly so) that my code will be reviewed by many people in the near future, and then added onto after a bit.

      In fact, working at Research In Motion has shown me how to write better code... sometimes, the most efficient or clever solution are the worst. I would rather see longer variable names, descriptive control structures and a total lack of goto statements. If you write sensible code, and use an optimization setting of 4 or 5, then you will have better programs in the long run. Also, the more complex and "optimized" your code is, the less chance the compilier would be able to optimize it and may even slow it down a little.

      But the biggest thing is to make it readable... I think writing code that executes SO FAST would be useful only in real time systems and large servers.

      Now... back to my realtime system... gotta make those blade servers smoke!

      --
      while(1) { fork(); };
    9. Re:Clear Code by caryw · · Score: 1

      You can code in a way that is both easy to understand and efficient. That's what //comments are for.
      Then again enough comments and the code becomes pretty murky.
      My favorite code editor (little windows program called pcGRASP) has a button that will hide/show all code comments. Very useful when trying to see just the beef through a mountain of comments.
      --Fairfax Underground: Where Fairfax County comes out to play

    10. Re:Clear Code by oringo · · Score: 1

      I agree with the clear coding style. Even if the compiler does generate a few more instructions, I would sacrifice a fraction of performance for code maintainability, clearity, and portability. On a typical workstation where interactive programs dominate, cpu utilization is so low that even if your applications runs a little slower it won't matter. The computer is waiting for user's input most of the time anyways. On servers, such performance loss can be compensated by the fact that next year's computer will always run faster.

    11. Re:Clear Code by SIGPUNKT · · Score: 2, Insightful
      Amen! If you're not already sweating optimization (i.e., you've got some supremely high-performance code), then it's better to write straightforward code. Especially with C, which has pretty mature compilers.

      Another thing to consider is that compilers for a modern RISC architecture have pretty intense optimization built in just to handle the instruction scheduling (re-ordering instructions to avoid pipeline stalls, etc.) that any trivial optimizations you might make would be "lost in the noise" anyway.

      That said, the big optimizations will always be worthwhile: cacheing results so you don't have to read from a file/database again, using lazy initialization to avoid populating data structures you may not use, validating inputs so you don't get halfway through an expensive operation and then have to roll back the transaction and throw an error, etc. But moving loop invariants? Maybe in a new language with an immature compiler, or a scripting language (just how efficient is PHP, anyway? Python?), but any modern compiler will make that irrelevant.

      --
      Where am I to go, now that I've gone too far?
    12. Re:Clear Code by pz · · Score: 2, Insightful

      This is absolutely true. Even if you are the only programmer who will ever look at the code. 10 years from now, when you're called on to fix a bug in something you wrote, you'll be extra glad that you took the time to write clearly, and comment liberally. Anyone else who comes across your code will thank you as well. And I'm speaking with nearly 30 years' experience as a programmer (and two CS degrees from MIT).

      In particular, unless you have very specific efficiency needs, modern CPUs are more than up to the task for nearly anything we can think of these days, further ameliorating the need for trading optimization against clarity. That said, there still remain applications which are CPU-bound. In such cases where hand optimization makes a difference, I usually first write a clear, general-purpose version of the code to make sure it works correctly. Then, I'll special case highly optimized versions where all bets are off for readability and maintainability, but will retain the clear version for the general purpose case. This does two things: first, it provides a soft intro to the algorithm in unoptimized fasion, aiding future maintenance; second, it provides a benchmark against which performance and correctness of the optimized code can be tested. If code size becomes a serious issue (for example in embedded applications), the clearly written reference code gets put in a comment above the highly optimized code. But in any case, the clear, correct version is retained.

      The importance of clearly written code (and the process of writing code clearly) is difficult to overstate.

      --

      Put my fist through my alarm clock with its ding-dong death inside my ear. - The Blackjacks.
    13. Re:Clear Code by android79 · · Score: 1, Interesting

      Actually, 'since' is incorrect (or atleast less correct, depending on whom you ask). 'Because' would be a better word in that case.

      'Since' implies a temporal relationship while 'because' more clearly shows a causal relationship.

    14. Re:Clear Code by Sancho · · Score: 0, Offtopic

      Fascinating. Even though you were nitpicking grammar, I'd mod this informative because I didn't know the distinction before!

    15. Re:Clear Code by Anonymous Coward · · Score: 0

      Personally I prefer self-documenting code, i.e. the variable names, object names, function names etc all have meaning and aren't just incomprehensible acronyms.

      Comments are good, but it's no use having excessive comments if the code is still unreadable. The one thing I tell my team more often than anything is to keep the code simple and readable. If something is inefficient then we'll optimise, otherwise leave it to the compiler to decide what is most optimal for the CPU. All IMHO of course.

    16. Re:Clear Code by Anonymous Coward · · Score: 1, Insightful
      Now... back to my realtime system... gotta make those blade servers smoke!

      It sounds unlikely that those blade servers are a realtime system, and it sounds even more unlikely you even know what a real time system is. Hint - blade servers almost certainly have far too many components with uncertain timing characteristics to be used in a real time system.

      I think writing code that executes SO FAST would be useful only in real time systems and large servers.

      It's perhaps even more valuable in high-volume low-cost systems. A DVD player (a very soft real-time system) that can get by with 1 microcontroller instead of 2 is worth tens to hundreds of millions of dollars to DVD manufacturers.

    17. Re:Clear Code by kuom · · Score: 1

      I have always believed that writing good, clear comments/documentation is more important than writing good code. As long as you can communicate well (in plain human language) what you are trying to accomplish, someone else smarter can come along and make your code better.

      And really, code optimization is rarely the bottle neck.

    18. Re:Clear Code by Anonymous Coward · · Score: 0

      it wasn't a grammar correction, he was stating that others viewing your code is more a certainty than a possibility (i.e. he was making a joke.) MELLOW OUT FUCKSTICK

    19. Re:Clear Code by Anonymous Coward · · Score: 3, Insightful

      Naturally. However, the example is retarded. I use the simpler form precisely because it's clearer and more expressive.

      "if (!ptr)" translates perfectly clear into english as "if no (valid) pointer" while "if (ptr==NULL)" involves some spurious special case value that I need to spend extra tinkering with.

      It's like comparing booleans with "if (foo==true)" instead of "if (foo)". If that's better why not go all the way and write "if (((...((foo==true)==true)==true)...==true)==true)" ? For extra clarity you should probably make a recursive function out of it.

    20. Re:Clear Code by nick_urbanik · · Score: 1
      You can code in a way that is both easy to understand and efficient. That's what //comments are for.
      It is a good rule of thumb to let the code explain itself as much as possible. If you use cryptic variable names and obscure premature optimisations, you may end up losing your code in comments.
      Then again enough comments and the code becomes pretty murky.
      See what I mean?

      Premature optimization is the root of all evil.--- Tony Hoare

    21. Re:Clear Code by smittyoneeach · · Score: 3, Funny

      You mean that we should not strain after a redundant temporary object gnat and swallow a network socket camel?
      If you are caught thinking out of the box again, you will get no dessert!

      --
      Get thee glass eyes, and, like a scurvy politician, seem to see things thou dost not.--King Lear
    22. Re:Clear Code by jallen02 · · Score: 2, Informative

      Not to mention if you write "correct" and cohesive code you can easily optimize it.

      As long as you don't over architect or go to extremes of abstraction your can do some very well abstracted code that pretty nicely separates all of the things that change from the things that stay the same. When you create this kind of separation optimization becomes easier and easier.

      Good (simple) examples are creating a generic interface to sort. You may start off with a simple insertion sort (why bother with heap/quick if you don't need it?). Anyone can understand insertion sort and its fine for relatively small sets of data. Then you expand the scope of the program and realize you need a better sorting algorithm. No problem! You go in and change the behind the scenes sort. Your interface to sort did not change and your program happily works just how it did. You apply this very same idea to as much of the software you write as is reasonable. Separate out data models and logic and displays. Keep each part of the system doing one task and doing it well.

      If the system is written good enough you don't even need anything but high level comments explaining the "big picture" of what is going on. I hate comments that are like the following:

      /* Set foo to 10 */
      int foo = 10;

      Well thank you captain obvious!

      Much better is an explanation over a block of 5-10 lines giving you an idea of what you are trying to achieve. Comment any thing that is not clear, like if your using bitwise shifts to multiply and divide, for example.

      Strive for simplicity :)

      Jeremy

    23. Re:Clear Code by david+duncan+scott · · Score: 4, Interesting
      Yup, that's why your bank throws away all three zillion lines of COBOL every year -- because there's a greater risk in maintenance than in new code.

      I wish I could put my hands on an article I read a couple years back on the code in the Space Shuttle. They go at that code base with an attitude that makes the average paranoid look happy-go-lucky. In fact, they approach software engineering kind of like other engineers do -- as if lives depended on it. It's old, it's slow, and it works. (Oh, wait, here it is.) That's how code is maintained.

      --

      This next song is very sad. Please clap along. -- Robin Zander

    24. Re:Clear Code by DG · · Score: 1

      Put me on the "me too" list.

      As a coder, your first priority is to optimise for human legibility. Ideally, you should be able to use any code snippet you write as a tutorial on that particular algorithm for a complete newbie.

      This is an investment in the quality of the code after it has been released. The easier it is to read and understand, the easier it will be to fix the bugs that are ALWAYS discovered once code reaches the users.

      Incidently, it may not be some faceless nobody who benefits from your forward-thinking - it may be YOU. Prolific, expert coders work on a LOT of different projects, and what is second-nature today may be long forgotten tomorrow. That obscure obfuscated nifty hack may come back to bite you some day.

      Most of the production stuff I wrote during my tenure at a Big 3 auto manufacturer was done in perl. There is a language that lets you be as clever and obscure as you wish. Not once did I ever regret choosing to optimise for legibility - and besides, it's cool to have some junior coder come up to you one day and tell you that your code, that he inherited, taught him how to use the language.

      And an odd side effect... I can't prove this rigourously, but it seems sometimes that code optimised for legibility seems to compiler-optimise particularly well. Subjectively, not only are your intents clear to some future maintainer or collabirator, but also to the COMPILER itself. After all, what's a program if not a conversation between yourself and the compiler?

      DG

      --
      Want to learn about race cars? Read my Book
    25. Re:Clear Code by Surt · · Score: 1

      CamelCase is wonderful if you have smart type code completion that supports it. So much better than the useless hungarian notation junk.

      --
      "Who is the Journal of Quantum Physics going to believe?" --Stephen Hawking
    26. Re:Clear Code by david+duncan+scott · · Score: 1

      Maybe. Or maybe it'll be the highly specialized guy who hired on last week because seniority hath its priviliges and it's much more fun writing new code then fixing the old stuff.

      --

      This next song is very sad. Please clap along. -- Robin Zander

    27. Re:Clear Code by lgw · · Score: 1

      There's always going to be a highly specialized, small team working on a particular piece of code. Unless, of course, you're talking about OSS.
      Not in my experience. Sure, at any give time there are only a few people maintaining a given peice of code, but ten years later those that remeain don't rememebr any of it. Clarity is always precious.

      --
      Socialism: a lie told by totalitarians and believed by fools.
    28. Re:Clear Code by peragrin · · Score: 1

      Live due depend on it.

      The shuttle goes up and explodes because the software controlling the rocket propellent mixture BSOD'd seconds after lift off. Not going to happen.

      Also The shuttle's have been getting upgrades, Digital displays, etc. But the testing on that stuff is literally out of this world.

      --
      i thought once I was found, but it was only a dream.
    29. Re:Clear Code by Anonymous Coward · · Score: 0

      camelCase and PascalCase actually, you got it wrong.

      camelCaseIsThis (internal visibility)
      PascalCaseIsThis (public visibility)

    30. Re:Clear Code by x736e65616b · · Score: 1

      He wasn't nitpicking grammar - read it again.

      -j

    31. Re:Clear Code by Tr0mBoNe- · · Score: 1

      yep, and when you write code for servers that deal with over 10,000,000 email messages per day, where downtime means you also loose your job, and where the difference between 1,000,000 users and 100,000,000 users is 100 ms in transfer time, you get a 'unique' perspective on what is what in the world of telecommunications.

      Also, the blades I use are great small scale testing servers. I have 8 sitting on one rack, and i can simulate incredable loads and unique conditions before we send them over to the 'real world'.

      --
      while(1) { fork(); };
    32. Re:Clear Code by joshdick · · Score: 2, Insightful

      I've heard this very example used many times in the past, and I think it's ridiculous. Any programmer knows that (!ptr) is the same as (ptr == NULL), so what makes you think one is clearer than another?

    33. Re:Clear Code by arivanov · · Score: 1, Offtopic
      Really just do not make me start.

      So, did working at RIM teach you to put a fixed timeout on the time it takes to complete a mail fetch operation even for protocols that report mail message size and hence allow you to _estimate_ how long it will take? By the way if you do not understand what timeout I am talking about it is the 150s limit to fetch in the RIM server software. The retarded piece of garbageware always cuts the connection regardless of data transfered after 150s and aborts all data. That is even for IMAP which allows partial fetch per part and has already given you full size and header information. Classic example of HOW NOT TO DO NETWORK PROGRAMMING

      So did working at the RIM teach you to add the Sender header field to the reply-to mail recipients when a user hits Reply-to-All? Where exactly it is in the RFC822 that the sender is anything and you have to reply to him as well when replying to mail? And if you do not understand to what it leads here is a classic example of one of my least favourite politicians telling BBC to fuck off. http://news.bbc.co.uk/1/hi/uk_politics/4247237.stm Good advertisement for RIM by the way

      Or it is just the usual Retarded in Motion attitude of "We invented the email, the Internet and everything around it". At least this is the answer I am getting every time I try to file these as bugs. The answer is "our software is working correctly and shall not be changed".

      It is nice that you talk about better code, but frankly you got the wrong company to present as an example. Because in order to produce good code you have to honour and understand the protocols and the specs you deal with and RIM is one of the most profound examples of people who do not.

      --
      Baker's Law: Misery no longer loves company. Nowadays it insists on it
      http://www.sigsegv.cx/
    34. Re:Clear Code by Smallpond · · Score: 1, Insightful
      My rule is never comment what the program does, comment why it does it.
      // Will crash if no files are open
      if (count == 0) {
    35. Re:Clear Code by NanoGator · · Score: 1

      "I think writing clear and easy to understand code is more important in the long run, especially if other people will have to look at it."

      That and resources (memory, cpu cycles etc) are getting so plentiful that we're reaching a point of diminishing returns.

      --
      "Derp de derp."
    36. Re:Clear Code by nmx · · Score: 1

      Oh, you work at Research In Motion? Your write better code? Like, code that causes Blackberry Server Management to lock up for no reason whenever I add a new user? That code?

      --
      "Well kids, you tried your best, and you failed. The lesson is, never try."
    37. Re:Clear Code by oliverthered · · Score: 2, Insightful

      I don't see where there is a contradiction, well unless the guy reading you code can't understand a quick-sort, even with enough comments to write a book on the subject.

      The optimisation rules are.

      Good algorithms, beats any optimisation of bad ones hands down.

      The make sure you know what the algorithm does, that way you can possibly minimise work.
      (e.g. a div is just a lot of subtracts and shifts)

      then good 'hints' for the compiler.

      then do it by hand if the compiler it making a mess of things.

      Consider that I could write a 'fast' Word processor in VB3(all interpreted) when compared to one written in C fully optimised, because I make good algorithm choices.

      There's a HSV colour picker in one application that is slow as a dog, they could have used a look-up table and made it possibly a hundred times faster. (near real-time, vs visible delay)

      as far as the code examples.

      I think you should use if(NULL == something), that way the compiler will choke if you type if(NULL = something) by accident.

      some people say just use HeapFree, because it checks nulls and is fast, I say check the null when expected and not when not.

      --
      thank God the internet isn't a human right.
    38. Re:Clear Code by Sancho · · Score: 1

      Ah, indeed!

    39. Re:Clear Code by Rei · · Score: 5, Insightful

      An important lesson that I wish I had learned when I was younger ;) It is crazy to start optimizing before you know where your bottlenecks are. Don't guess - run a profiler. It's not hard, and you'll likely get some big surprises.

      Another thing to remember is this: the compiler isn't stupid; don't pretend that it is. I had senior developers at an earlier job mad at me because I wasn't creating temporary variables for the limits of my loop indices (on unprofiled code, nonetheless!). It took actually digging up an article on the net to show that all modern compilers automatically dereference any const references (be they arrays, linked lists, const object functions, etc) before starting the loop.

      Another example: function calls. I've heard some people be insistant that the way to speed up an inner loop is to remove the code from function calls so that you don't have function call overhead. No! Again, compilers will do this for you. As compilers were evolving, they added the "inline" keyword, which does this for you. Eventually, the compilers got smart enough that they started inlining code on their own when not specified and not inlining it when coders told it to be inline if it would be inefficient. Due to coder pressure, at least one compiler that I read about had an "inlinedamnit" (or something to that effect) keyword to force inlining when you're positive that you know better than the compiler ;)

      Once again, the compiler isn't stupid. If an optimization seems "obvious" to you, odds are pretty good that the compiler will take care of it. Go for the non-obvious optimizations. Can you remove a loop from a nested set of loops by changing how you're representing your data? Can you replace a hack that you made with standard library code (which tends to be optimized like crazy)? Etc. Don't start dereferencing variables, removing the code from function calls, or things like this. The compiler will do this for you.

      If possible, work with the compiler to help it. Use "restrict". Use "const". Give it whatever clues you can.

      --
      "Lock and load, Brides of Christ!"
    40. Re:Clear Code by B'Trey · · Score: 2, Informative

      Some experts seem to disagree with you.

      --

      "The legitimate powers of government extend only to such acts as are injurious to others." Thomas Jefferson.

    41. Re:Clear Code by Coz · · Score: 2, Insightful

      Remember - compilers don't care about comments!

      --
      I love vegetarians - some of my favorite foods are vegetarians.
    42. Re:Clear Code by LnxAddct · · Score: 1

      A compiler never gets bored or tired, so yea writing clean code is smart. Let the compiler do the optimizations and overall you'll probably see it do a better job then you ever could. A compiler might not see everything you might (i.e. !ptr and (ptr ==NULL) being equal, this is just an example, thats probably not a true statement), but the compiler will also spot things you never would. On average it will always beat you out. Of course if you really need speed then start profiling your code, optimizing code as much as you can where its needed most in conjunction with the compiler optimizations will help greatly.
      Regards,
      Steve

    43. Re:Clear Code by oliverthered · · Score: 1

      ' I would rather see longer variable names, descriptive control structures and a total lack of goto statements'

      How does this objective work against the most efficient or clever solution.
      (ok lack of gotos can sometime be a pain, but you can usually innline that away, or 03 it out)

      optimise settings on GCC above 3 are useless, generally go for 2 as you tend to get tighter code that fits in cache better.

      --
      thank God the internet isn't a human right.
    44. Re:Clear Code by Anonymous Coward · · Score: 0

      Yes, that's great and all, but it's still not real time.

    45. Re:Clear Code by drgonzo59 · · Score: 1
      I agree. I noticed when I try to optmize my code by making it shorter and more concise, I end up shooting myself in the foot, because later I have to spend more time figuring out is that I was doing in that part of the code.

      Besides, in general it is far better to optimize the algorithm, if possible, and then optimize the individual code snippets. In other words try to optimize on a grand scale (a compiler won't help you here, but a Comp Sci degree might) then on a smaller scale down to individual lines, provided there is enough time.

    46. Re:Clear Code by DJStealth · · Score: 4, Insightful

      Take the following example that is clear, but only 1 is considered optimized.

      Lets say you're traversing a 2D array of data (e.g., an image).

      for(x=0; x < width; x++)
      {
      for(y=0; y < height; y++)
      {
      ...
      }
      }

      versus

      for(y=0; y < height; y++)
      {
      for(x=0; x < width; x++)
      {
      ...
      }
      }

      The latter piece of code is just as clear as the first; however, will likely run about 50 times faster than the first, due to caching issues.

      Will the compiler optimize the first piece of code to look like the second? Probably not (tell me if I'm wrong), as there may be a reason to process things in a particular order.

      In addition, the latter piece of code may actually be less clear, as in some cases, it may not read well to do height before width in the for loop.

      As a result, you'll still need to write code thinking about optimization.

    47. Re:Clear Code by Anonymous Coward · · Score: 0

      You write code like your going to have to figure out what it is doing [or not] at 3 A.M. Not sooner, not later.

      wb

    48. Re:Clear Code by OrangeTide · · Score: 1

      I prefer that style, because _ is so far away to type. But you can argue forever about how acronyms should be handled.

      convertIpToString vs. convertIPToString

      Funny thing with _ method though is that you'd think putting a whole extra character between every word would result in longer symbols, but camelCase seems to encourge long symbols.
      real world example:

      CGOpenGLDisplayMask dispmask = CGDisplayIDToOpenGLDisplayMask( kCGDirectMainDisplay );

      --
      “Common sense is not so common.” — Voltaire
    49. Re:Clear Code by Anonymous Coward · · Score: 0

      > I think you should use if(NULL == something), that way the compiler will choke if you type if(NULL = something) by accident.

      Yes, and a decent one will warn you about accidental assignment. I compile with -Werror myself, and if I just can't avoid a warning, I will #pragma it out.

    50. Re:Clear Code by Explodo · · Score: 1

      It really depends on if you're writing code that needs to be fast or not.

      Now, please don't think ill of me for this, but I just wrote a single function that is over 6000 lines of code. That's including some MACROS that were written specifically for the function so the line count wouldn't be over 8000 lines. It's written purely for speed. Since function calls have overhead, they were all removed. The code is a line-of-sight check for a hexagonal grid with asymmetricaly layers. The function is called very frequently and speed of execution is far more important than good style in this case. I did everything that I could to make it run faster, at the expense of simplicity and style. It runs 3.5 times faster than the old code with much more information gleaned in the process.

      I'm sure many slashdotters would look at the code and their eyes would bleed, but when speed matters most, that's what you get.

    51. Re:Clear Code by black6host · · Score: 1

      Code should document itself. In most cases comments should be used to document business rules used that can't be determined from the code being read. A combination of this and the lack of use of magic numbers makes for easier to maintain code, in my opinon. Of course, maintaining business rules in a separate area is even better.

    52. Re:Clear Code by Trillan · · Score: 1

      An important lesson that I wish I had learned when I was younger ;) It is crazy to start optimizing before you know where your bottlenecks are. Don't guess - run a profiler. It's not hard, and you'll likely get some big surprises.

      Another thing to remember is this: the compiler isn't stupid; don't pretend that it is.

      Correction: Some compilers aren't stupid. Others are. I used to rely on compilers to optimize my code. Metrowerks Codewarrior taught me otherwise.

      1. Consider what you need the code to do.
      2. Consider the algorithm you plan on using.
      3. Write the code.
      4. Make sure it works according to #1.
      5. Save the code to your repository.
      6. Eliminate redundant operations and unroll calculations (whether integer or floating point) in loops when possible.
      7. Make sure it still works according to #1.
      8. Save the code to your repository.
      9. Rather than guessing if the compiler has done a good job of compiling it, dump the produced object code and read through it. Among other things, the altenrate way of describing your code may help you spot situations you didn't think of while writing the source.
      10. Make sure it works according to #1.
      11. Save the code to your repository.
      12. Leave it alone for now, but profile it later.

      Is it necessary? Well, maybe not, and it certainly doesn't replace profiling. But it certainly isn't crazy to check your code carefully when you write it. (If you have to do only one, though, certainly profiling is the more important of the two.)

    53. Re:Clear Code by Anonymous Coward · · Score: 0

      The Columbia Guide to Standard American English disagrees with you.

    54. Re:Clear Code by Matt+Perry · · Score: 2, Insightful
      An important lesson that I wish I had learned when I was younger ;) It is crazy to start optimizing before you know where your bottlenecks are.
      It's like that saying:

      Rules of Optimization:
      Rule 1: Don't do it.
      Rule 2 (for experts only): Don't do it yet.

      --
      Slashdot: Failed Car Analogies. Amateur Lawyering. Anecdote Battles.
    55. Re:Clear Code by lymc · · Score: 4, Interesting

      Now, let me tell you the flip side of that story. I was working on the Viking Mars Lander program long ago (1976). The code for the lander programs was frozen a year before launch (which itself was a year before landing). Some dozen "books" of the assembly code were created and archived for use when the landers finally landed. All went well for about 6 months after landing. Updates were made and duly entered into the master asssembly listings. After six months of this, the listings were so xed out, and all the margin space used with notes, that errors started creeping in. Finally an uploaded patch wrote over part of the antenna pointing table, and the lander was lost, but for a fortuitious accident which allowed the table to be re-established (with much howling and gnashing of teeth). Sometimes new is better, even if it is painful.

    56. Re:Clear Code by maetenloch · · Score: 1

      Remember processors will always get faster and compilers will optimize better over time, but programmers probably won't ever become much smarter, so you should always write your code with the programmer working on it five years from now in mind.
      Other than tight loops in an application with real-time requirements, clear and simple code is the better choice.

    57. Re:Clear Code by oliverthered · · Score: 1

      I would also like to compile everything with compile with -Werror, but my Gentoo can't take it, as it is compiling with -Werror-implicit-function-declaration causes some builds to fail at configure time.

      Until the day when everyone uses pragmas or gcc ship with -Werror hard-on, I'm going to keep telling people to use CONSTANT == just incase.

      wow, I managed to use hard-on in a sentence, I'll have to try that in an interview someday.

      --
      thank God the internet isn't a human right.
    58. Re:Clear Code by mveloso · · Score: 2, Interesting



      Well, in Java this may speed things up. All instance variable references won't be cached locally. It's been a while since I checked this, but I believe that it's still true. Just something to think about if you're looping a few million times.

      Sometimes it helps, sometimes it doesn't. The only way to really know what your compiler does is to look at the output of the compiler, and understand what all those switches do.

      Now there are some things you can do to optimize your code while you're writing it, but a lot of that is heavily dependent on your platform, runtime, and environment. In general, you should write your code in a straightforward way, then write an optimized version of it later (if you determine it's necessary).

      Of course, the best way to help your optimizer is to write things in the simplest manner possible.

    59. Re:Clear Code by Tony+Hoyle · · Score: 2, Insightful

      Indeed.. the example is totally backward.

      if(!ptr) is 'if not pointer' - which makes perfect sense to any programmer and anyone who has even a passing knowledge of boolean logic.

      I've seen the '== true' and '== false' things around and really hate them as they're not nearly as legible.. Worse is '!= false' and '!= true' - you have to actually stop an think what that means as it's a double negative.

    60. Re:Clear Code by oliverthered · · Score: 2, Insightful

      That should be "especially since _I_ will have to look at it _later_"

      Don't just write nice code for other people to read, write it for yourself.

      --
      thank God the internet isn't a human right.
    61. Re:Clear Code by ArbitraryConstant · · Score: 2, Interesting

      When passing pointers, the "const" thing is a big deal.

      It has to make sure it uses the copy in memory everywhere if anyone else gets a copy of the pointer. That function might keep a copy, pass it around there's no way to know.

      If you use "const" in the function decleration, it can assume no one elsewhere will be changing it.

      Of course, in my always humble opinion using a compiled language at all is a premature optimization most of the time. :)

      --
      I rarely criticize things I don't care about.
    62. Re:Clear Code by Nutria · · Score: 1

      Why would you? There's always going to be a highly specialized, small team working on a particular piece of code.

      You're still in University, aren't you?

      --
      "I don't know, therefore Aliens" Wafflebox1
    63. Re:Clear Code by Anonymous Coward · · Score: 0

      You American's have a weird sense of humor, the oh the irony of it all.

    64. Re:Clear Code by Tony+Hoyle · · Score: 1, Insightful

      How will one run 50 times faster than the other? All you did was swap the variable names around.

    65. Re:Clear Code by ArbitraryConstant · · Score: 1

      Also, there are often libraries with all the fancy optimizations all wrapped up in a neat little package. Better to use those than litter your code with anything hard to read.

      --
      I rarely criticize things I don't care about.
    66. Re:Clear Code by Anonymous Coward · · Score: 0

      True. And if you want to optimize your program, optimize the algorithms, not the code. You can gain something like 1 microsecond if you optimize the code. And you can get execution times that are even months better than the old ones were, if you just fix the algorithms.

      Sometimes fixing the algorithms even makes the code simpler to read.

    67. Re:Clear Code by lubricated · · Score: 5, Insightful

      well the first thing to optimize is the algorithm. Use a O(n^2) algorithm that does the same job as an O(e^n) algorithm if you can. Algorithmical optimization makes the most difference. I am working on a program who's speed is directly proportional to how how often a particular function is called. Well, I try to reduce calls to this function by various means, no compiler I've sean can optimize an algorithm, only the implementation of it. With that I'm happy to have the compiler do the work.

      --
      It has been statistically shown that helmets increase the risk of head injury.
    68. Re:Clear Code by Mr_Huber · · Score: 1

      Any C programmer knows this. It is not true in all languages. And symantically, if you are checking to ensure that a pointer is not null, (ptr != NULL) is more correct. (!ptr) uses a quirk of C, that null pointers and the boolean state false have the same internal representation, to affect a comparison.

    69. Re:Clear Code by rs79 · · Score: 1

      "Even if you are the only programmer who will ever look at the code. 10 years from now"

      10 years? Try six months.

      As as teen I was the guinea pig for Dave Conroy's C compiler in 1976 (now gcc) and back then we looked at every PDP 11/34 instruction it generated. Next, with a Z80 you still had to do it but not as much. Once we got to 68000 and x86 (spit) machines, forget it. It'll be fine.

      With todays modern processors (ever see a pocket sized Pentium instruction set reference? me either) even with the the knowledge that 90% of the time you execute 10% of the code it just doen't matter.

      In the very few cases where it does matter - and these are exteme cases, you can still always hand optimaize some tight inner loop in assembly.

      I'm told Alta Vists had a 6 instruction hand coded assembler bit and the rest was "just C".

      Keep in mind too extereme performance tuning this way throw portability out the door. While it'd be great to see somebody, say, do Postfix filter rules in assembly utilizing fully the whacko instructions on a Pentium, you lose posrtability.

      But, and this is a but of epic proportion, nothing beats being able to understand instantly what a statement is doing; I write excessiviely verbose long drawn out lots of whitespace C, use no tricks and assume my kids have to read it knowing only BASIC.

      I doubt this has ever saved my ass, but the less I have to think, the better for everybody. Trust me on this.

      And besides, in most cases CPU doesn't matter. Faster disk, more RAM, faster net connection more RAM and more RAM go a long way before you get around to needing faster code execution.

      So while I used to check every single friggin bit and instruction in the beginning I don't even bother thinking about optimization levels or fine tuning code. But it's not like I write code that takes 40 hours to run or do video games - obviously realtime progamming needs a bit more atention to detail. I think. It used to when I was doing it but that's been a while.

      "The importance of clearly written code (and the process of writing code clearly) is difficult to overstate"

      s/difficult/impossible

      --
      Need Mercedes parts ?
    70. Re:Clear Code by krunk4ever · · Score: 0

      Really depends if your job is replacable.

      Here's a guide on How To Write Unmaintainable Code.

      In the interests of creating employment opportunities in the Java programming field, I am passing on these tips from the masters on how to write code that is so difficult to maintain, that the people who come after you will take years to make even the simplest changes. Further, if you follow all these rules religiously, you will even guarantee yourself a lifetime of employment, since no one but you has a hope in hell of maintaining the code. Then again, if you followed all these rules religiously, even you wouldn't be able to maintain the code!

    71. Re:Clear Code by eric76 · · Score: 1

      One of my favorite approaches is to write the comments before the code.

      Then, if the comments need to be modified to reflect the code, change them.

    72. Re:Clear Code by eric76 · · Score: 2, Informative

      Because of the way the data is stored.

      It is faster to process the data sequentially than to skip around.

      That is especially true if the data elements are small such as chars. You would end up having to fetch the same data from memory multiple times in the processing of one loop compared to only once in the other loop.

    73. Re:Clear Code by uglyduckling · · Score: 1
      Exactly - I write code with whatever shorthand or optimisations I want, but if I have to pick my way through a block of code a week later then I'll put comments all over it for my benefit - and anyone else who might want to look at it in the future.

      Just as an aside - the example given isn't that clear, but I find that if variable names are sensible then using implicit conditional tests can make things clearer. E.g. I find if(finishedsearching) and if(!finishedsearching) clearer than if(fs==TRUE) and if(fs==FALSE). Just personal style I guess.

    74. Re:Clear Code by Glonoinha · · Score: 1

      If you can't be replaced, you can't be promoted.
      That's one good reason to document your code ...

      --
      Glonoinha the MebiByte Slayer
    75. Re:Clear Code by Trillan · · Score: 1

      I couldn't agree more. I recently wrote some routines for a 68000. My original implementation took 2 seconds for my test case. Once I studied and improved my algorithm a bit more, I not only got the time down to 0.29 seconds, but improved the accuracy of the alogirthm as well.

      I did this before porting the code to a much faster achitecture (you can choose between 68000 or ARM code on the Palm). Just for the fun of it, I posted both algorithms. The original algorithm came in at 0.83 seconds, and the optimized one at 0.04 seconds. So I gained more by tuning the algorithm than by switching out of the emulated environment to the real one!

      This last point is the basis for most "Java is faster than C!" arguments, and doesn't take into account that you can usually tune the C code as well. (Not saying Java is slow, mind you, just that it's not faster.)

    76. Re:Clear Code by Anonymous Coward · · Score: 0

      Looking at your homepage link, gotta ask: do you program in Java in your job at RIM? J2ME programming?

      Curious to know, and hoping you all do use J2ME!

    77. Re:Clear Code by Anonymous Coward · · Score: 0

      He works at RIM? Man that must be great.
      How does one go about getting a RIMjob?

    78. Re:Clear Code by Dun+Malg · · Score: 1
      How will one run 50 times faster than the other? All you did was swap the variable names around.

      He didn't fully describe the situation. I think he probably means that the inside loop calls some sort of pixel lookup function that takes x and y as input. The presumption is that, for a large image, the system can cache perhaps a horizontal line's worth of info at a time, and subsequently a routine that scans horizontally across one line at a time will be faster than one that tries to scan vertically.

      --
      If a job's not worth doing, it's not worth doing right.
    79. Re:Clear Code by Nutria · · Score: 1

      I have always believed that writing good, clear comments/documentation is more important than writing good code.

      And then a change order comes in which subtly alters the meaning of the code. Unfortunately, the dumb ass who was assigned to the task, since you were on vacation, didn't update the comments.

      So, remimd me never to work on the same code you do.

      --
      "I don't know, therefore Aliens" Wafflebox1
    80. Re:Clear Code by drgonzo59 · · Score: 5, Interesting

      Same goes for code that runs on the airplanes (like Boeing passenger aircraft). In fact the developers have to prove that each possible! branch that code could ever take won't lead to unpredictable behavior or crash. If you have 100 independent 'if' statements that is at least 2^100 possibilites. The code they write is very linear, they avoid branching at all cost.

      There is a whole are of study involved in correctness checking, which is related to the SAT (Satisfiability) problem.

      The operating system choice is also interesting. Linux doesn't even come close to what they need. Having device drivers in the kernel is just not a good idea. It needs to have a separation kernel, at least that is the goal. I presently think they use the INTEGRITY operating system by Green Hills, but I could be wrong.

    81. Re:Clear Code by Anonymous Coward · · Score: 0
      Caching. Compilers store the rows in a 2D array one after another. (Or the columns, depending on the language/compiler/options.) If you walk through the array in row order, most of the data will already have been prefetched into the cache. In you walk through in column order, the first row is likely to have been flushed out of the cache by all the other rows by the time you get back to it. Accessing arrays in the right order is of major importance.

      Similar benefits can be gained by deallocating data structures and reusing their memory as early as possible. The performance gains can be formidable, but you have to understand what the CPU is actually doing.

    82. Re:Clear Code by Nutria · · Score: 1

      And besides, in most cases CPU doesn't matter. Faster disk, more RAM, faster net connection more RAM and more RAM go a long way before you get around to needing faster code execution.

      You left out the most important item: better algorithms.

      --
      "I don't know, therefore Aliens" Wafflebox1
    83. Re:Clear Code by Thunderbear · · Score: 1

      I write a lot in Java, and even though that the syntax is the same, it is much harder to read the !-negation than the "== false"-negation.

      The reason is that -- in Java -- you very often dereference multiple objects on your way down to the field you need to test, so the negation and the value to negate tend to be far from one another on the line.

      I stared a lot on a snippet having exactly that error (an incorrect number of !'s) for much too long. A "== false" would have been much easier to spot.

      --

      --
      Thorbjørn Ravn Andersen "...and...Tubular Bells!"
    84. Re:Clear Code by Glonoinha · · Score: 1

      And besides, in most cases CPU doesn't matter. Faster disk, more RAM, faster net connection more RAM and more RAM go a long way before you get around to needing faster code execution.

      Yes and no.
      I can't envision many one-line statements that either the coder or the compiler could optimize to much of an effect, but consider the difference between bubblesort and quicksort.

      You can replace the computer with a machine 4x as fast with eight times as much memory and drives with seek speeds 1.5x faster than the last generation and maybe ... it can run the same code 3x faster. 5x faster if you are rich or lucky.

      Re-code the sort routine used on a zillion records from a bubble sort to a quicksort and it will go what, 1,000x faster (on the same hardware)?

      To the OP: the difference between !p and p==NULL is all in your head. If you can do some serious algorithm analysis and approach some of the fundamental routines in your code with better (more optimized) routines ... then you are getting somewhere. Other than that - just code it so you (or the guy you are responsible for when you get promoted) can figure out what it does when you need to change it, or quickly pinpoint bugs when they pop up.

      --
      Glonoinha the MebiByte Slayer
    85. Re:Clear Code by eric76 · · Score: 1

      In that case, the dumb ass should be moved to something else.

    86. Re:Clear Code by Snakera · · Score: 1

      So by that article what if machine #5 has flawed software that disagrees with the other 4?

    87. Re:Clear Code by severoon · · Score: 2, Insightful

      At every place I've worked, I've always had a standing bet open to any and all takers. You branch your code and I'll branch mine, you preoptimize and I'll write legible code that sticks religiously to good OO design principles. After the development cycle ends, if a profiling tool proves that your way is better in a significantly demonstrable fashion to the product, you win $100. If not, you owe me $50. (You can hammer out the terms of "significantly demonstrable," but it basically means that the code we're talking about falls into the 20% of the codebase--per the 80/20 rule about where execution flow spends most of its time--and my way is so much more grossly inefficient than yours it actually causes consternation in the end user.)

      Put like this, no one ever takes the bet. It's easy money for me. Even the strongest preoptimization advocates get pretty silent once the discussion is framed this way.

      Here's the thing. Except in certain, specific circumstances, e.g. real-time or embedded high-performance systems, lack of performance comes from bad design 99.9% of the time. If the design of the product accommodates the performance requirements properly, no optimization is usually necessary.

      Does optimization help in these situations? It depends on what you mean by "help". If you mean, does it make it faster, then yes. If you mean, does it make a better product, then the answer is most cases is indubitably: no. Faster, more fragile, less maintainable, and more poorly documented usually means worse for the product. And the kicker is, in most cases it doesn't improve performance in any meaningful way.

      Much better is to approach your architecture and design with an eye towards the specific performance factors and requirements of your product, and design things properly. This will get the big stuff (that you can't usually optimize your way out of anyway). Then somewhere near code freeze, set aside time to do profiling to the extent that gives you a good idea of where the CPU is burning most of its cycles. Usually that's somewhere between 5% and 10% of your code, and usually it's only reasonable to optimize in 5%-10% of that code, and usually there are only opportunities to do intelligent optimization in 5%-10% of that code. (Of course, this doesn't take into account all of the boneheaded code that somehow found its way into the product where just sticking to best practices shows not only markedly better code in terms of performance, but also in every other sense.)

      If you're still finding problems performance-wise, chances are you started off without addressing the right requirements in the first place. Go back to architecture, do not pass Go, do not collect $200.

      --
      but have you considered the following argument: shut up.
    88. Re:Clear Code by say · · Score: 2, Interesting

      no compiler I've sean can optimize an algorithm

      Although I definitely agree with your conclusions, the above sentence is not correct. Most implementations of Scheme, for instance, does a lot of algorithmic optimisations, basically by turning tail-recursion into (functional) iteration when possible.

      These kind of optimizations are extremely effective in some scenarios because it significantly reduces memory use and read/write of memory, and can be illustrated quite easily by turning optimization off in any good Scheme interpreter (like DrScheme).

      --
      Roses are #FF0000, violets are #0000FF, all my base are belong to you
    89. Re:Clear Code by Surt · · Score: 1

      Actually, it doesn't matter which you use, either way is great with a supporting editor.

      --
      "Who is the Journal of Quantum Physics going to believe?" --Stephen Hawking
    90. Re:Clear Code by Electroly · · Score: 1

      Wrong again. He's considering an array with elements in row-major order. That means that all of the values in one row are contiguous in memory. In a modern environment, memory reads are cached, or "read ahead." The system sees you reading one value and makes a reasonable assumption that you'll be reading the values that follow it pretty soon, so it caches them. When you process rows together instead of columns together, this works to your benefit because you're working out of cache for the entire row. If you process columns together, you're essentially skipping around in memory and, given a large enough array, the system won't have cached the entire column together.

    91. Re:Clear Code by 3.1415926535 · · Score: 1
      Metrowerks Codewarrior taught me otherwise.

      Metrowerks taught me to never trust anything from them, even for correctness.

      While working on an absolutely trivial Java program for a class in high school, I ran into this nice bug in the Metrowerks Java runtime that was available at the time: If you try to print a float who's value is exactly 0.0f, it would print "infinity" instead. Lead to code like this:
      if(var == 0)
      System.out.println("0");
      else
      System.out.println(var);
      Frustrating!
    92. Re:Clear Code by Explodo · · Score: 1

      I have profiled code with function calls and with the body of the function in place of the function call and it's definitely faster to use the in-place code. Not all code can be inlined. The compiler will ignore the inline if the code gets outside of a very restrictive set of constraints.

    93. Re:Clear Code by rve · · Score: 1

      This is off topic, but still:

      There may be many things wrong with old fashioned languages like COBOL, but it being slow is not one of them. An extremely rigid programming language without any dynamic memory allocation actually turns out code that can be optimized better by the compiler than something as flexible as C or C++

    94. Re:Clear Code by GryMor · · Score: 5, Informative

      It's working on a 2d array of data and is presuming that it is ordered as such:

      123
      456
      789

      data[y][x];

      This, in memory, is:
      123456789

      Similarly, the accsess order for the second loop is:
      123456789

      But for the first one, it is:
      147258369

      The first one hits memory sequentially, which is good for caching as each cache line stores a large chunk of sequential memory.

      Considering hitiing the cache as oposed to hitting main memory is at least 100 times faster, you'll be lucky if the first loop is only 50 times slower.

      This still presumes data stored in the specified order in memory (which is common for image formats, but not the only way things are done).

      --
      Realities just a bunch of bits.
    95. Re:Clear Code by frantzdb · · Score: 1

      A more-concise, and potentially more clear solution would be: for_each(foo.begin(), foo.end(), ...). Then the object over which you are iterating gets to decide how best to traverse itself, plus your semantics are at a higher level; you are saying what you mean, "do something for each element" rather than "go through in row-major order and then at that x, y do something".

    96. Re:Clear Code by iamlucky13 · · Score: 1

      The system is designed so that 4 computers handle the primary decisions and the fifth is a backup. My understanding is if one of the four yields a different result, it's treated as a minority report (just like the Tom Cruise movie) and disregarded. If they tie, it's considered a malfunction (probably double checked first) and the fifth computer makes the call. Bear in mind this is speculation.

    97. Re:Clear Code by eyegone · · Score: 1


      I would be more than happy to use restrict, if someone could provide a comprehensible explanation of what it means!

      --
      "They that can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety."
    98. Re:Clear Code by Ninja+Programmer · · Score: 2, Insightful

      Unfortunately, I've posted -- otherwise I would used my mod points to indicate this as a troll or overrated or something.

      The two expressions are semantically identical. There is no difference between the two. So "any programmer" who sees a distinction between the two, is just a defective programmer. Just use the one that follows your "coding conventions" if you've got them, or just use the one you are used to.

      This level of inane minutia is not what I would call "real programming", any more than typing skills are.

    99. Re:Clear Code by kryptobiotic · · Score: 1

      In the ... section, he is accessing the 2d array.
      Depending if your language stores arrays in column major order (like fortran) or row major order (like c/c++), the next accessed element of the array is either the very next element in memory or some element much farther away. Reading the elements in the same order they are stored in memory is much faster than skipping all over memory.

      Search for accessing memory here.

    100. Re:Clear Code by krick-zero · · Score: 1

      Since when do banks throw away COBOL code? A close friend was a programmer for Citibank. They were still using systems that were 15 years old or more because they can't risk implementing a new system and having it not work correctly. That's why the are still running ancient code on on ancient hardware. Banks get fined thousands of dollars a day by the govt when their books don't balance.

    101. Re:Clear Code by Greyfox · · Score: 1
      My rule is if the programmer can't figure it out, they shouldn't be working on my code.

      function1(foo, &bar);
      function2(foo, &bar);
      function3(foo, bar); /* DON'T CHANGE THIS LINE UNLESS YOU REALLY KNOW WHAT YOU'RE DOING */

      All the warning I think they need, don't you?

      On a slightly different note, it's becoming fairly common practise now to do comparasons with #define'd values on the left, because you can't accidentally make an assignment if you write "if (NULL=pointer)" wheras if you did it the other way around you'll have to fix a bug later. I still prefer !pointer personally, simply because I tend to find that to be more readable.

      --

      I'm trying to teach myself to set people on fire with my mind... Is it hot in here?

    102. Re:Clear Code by Explodo · · Score: 1

      Here's some example code to prove you wrong for MS VC++ 6.0 on Win XP. The function call takes 10% more time than the in-place code over 1 billion iterations. 77 seconds vs. 70 seconds.

      int q, steps = 1000000000;
      long location;
      int x, y, z;
      time_t first, second, third;
      time(&first);
      for(q=0;q<steps;q++)
      {
      //function
      GetCoordinates(4567, x, y, z);
      }

      time(&second);
      for(q=0;q<steps;q++)
      {
      //code from function
      location = GetLocationFromIndex(4567);
      location--;
      x=location % maxX;
      location=location / maxX;
      y=location % maxY;
      location=location / maxY;
      z=location;
      }

      time(&third);

      CString tempy;
      tempy.Format("Func: %d \tCode: %d", second - first, third - second);
      AfxMessageBox(tempy);

      If I can save 10% by removing function calls in a time-critical process, I will any day. Notice that I still have a function call in the code section. If I were to remove that, I would get even bigger gains.

    103. Re:Clear Code by Anonymous Coward · · Score: 0

      There is a whole are of study involved in correctness checking, which is related to the SAT (Satisfiability) problem.

      Please check the correctness of that sentence. I am not satisfied!

    104. Re:Clear Code by Dun+Malg · · Score: 1
      Wrong again. He's considering an array with elements in row-major order. That means that all of the values in one row are contiguous in memory. In a modern environment, memory reads are cached, or "read ahead." The system sees you reading one value and makes a reasonable assumption that you'll be reading the values that follow it pretty soon, so it caches them. When you process rows together instead of columns together, this works to your benefit because you're working out of cache for the entire row. If you process columns together, you're essentially skipping around in memory and, given a large enough array, the system won't have cached the entire column together.

      What do you mean "wrong again"? You described exactly the same thing I described.

      Me: "the system can cache perhaps a horizontal line's worth of info at a time"
      You:"He's considering an array with elements in row-major order. That means that all of the values in one row are contiguous in memory."

      Me:"a routine that scans horizontally across one line at a time will be faster... "
      You:"When you process rows together instead of columns together, this works to your benefit because you're working out of cache for the entire row."

      Me:"...will be faster than one that tries to scan vertically."
      You:"If you process columns together, you're essentially skipping around in memory and, given a large enough array, the system won't have cached the entire column together."

      Your description is more verbose, and describes it in generic terms rather than giving a common example, but it's the same goddamn thing. My only error perhaps was not making it entirely clear that my description was an example of what one might find inside the inner loop.

      --
      If a job's not worth doing, it's not worth doing right.
    105. Re:Clear Code by Anonymous Coward · · Score: 0

      Double negatives are very common and entirely natural in many languages, and indeed I did not know that anyone considered it unnatural until some Americans complained about it.

    106. Re:Clear Code by noidentity · · Score: 1

      > It's like comparing booleans with "if (foo==true)" instead of "if
      > (foo)". If that's better why not go all the way and write "if
      > (((...((foo==true)==true)==true)...==true)==true)" ? For extra
      > clarity you should probably make a recursive function out of it.

      I did, but it crashed :(

      inline bool is_true( bool b ) {
      return is_true( b ) == true;
      }

      So I just expanded it to about 10 levels. I even wrote a macro for it (shortened):

      #define IS_TRUE( x ) (((((x) == true) == true) == true) == true)

    107. Re:Clear Code by lubricated · · Score: 1
      doesn't work, unless the compiler can figure it out anyway.

      The following is perfectly valid code, though bad from a maintainability point of view.
      void dostuff(const char* foo)
      {
      char* bar;
      bar = (char*)foo;
      bar[0] = 'a';
      }
      --
      It has been statistically shown that helmets increase the risk of head injury.
    108. Re:Clear Code by Anonymous Coward · · Score: 0

      Except the Auburn folks dumped pcGRASP for jGRASP, which needs about a hundred times more RAM to work a quarter as quickly as pcGRASP, which is itself a descendent of GRASP for UNIX. pcGRASP is almost perfect, but has a handful of small bugs that won't ever get fixed (I like open source software for this reason). jGRASP would've been better if it'd been called AdaGRASP and written in Ada.

    109. Re:Clear Code by lubricated · · Score: 1

      either a poor compiler, or the optimization isn't turned on, or the function that is called is in another file.
      Newer versions of msvc(if you can get the optimizing ones which are quite expensive), do this much better.

      --
      It has been statistically shown that helmets increase the risk of head injury.
    110. Re:Clear Code by Electroly · · Score: 1

      You're right, of course. I need to get some sleep... I was just showing the generic array example which is what I assumed he was talking about, which applies in pretty much any situation. Your image example was totally correct.

    111. Re:Clear Code by Alsee · · Score: 1

      if(!Flag!=!False);
      else{DoStuff()};

      -

      --
      - - You can't take something off the Internet! That's like trying to take pee out of a swimming pool.
    112. Re:Clear Code by lubricated · · Score: 1
      These kind of optimizations are extremely effective in some scenarios because it significantly reduces memory use and read/write of memory, and can be illustrated quite easily by turning optimization off in any good Scheme interpreter (like DrScheme).


      sounds to me like it's not really changing your algorithm(same thing happens), but rather running it more efficiently. Or is there something I am missing?
      --
      It has been statistically shown that helmets increase the risk of head injury.
    113. Re:Clear Code by Salamander · · Score: 1

      Assuming that your compiler will fix your performance problems is as bad as assuming that it won't. Inline is a good example because (a) not everything can be inlined, and (b) inlining can create costs. If you use an inline function many places, it can increase code size and correspondingly reduce cache efficiency. If your compiler can handle the inline just fine but your debugger can't (e.g. screws up line numbers or breakpoints) your "fix" might waste valuable programmer time. Are inline functions handy? Sure. Should they be anywhere near the first set of things you should consider when you need to improve performance? Hell, no. Pick a good top-level structure, profile, and tune low-level algorithms. Using "inline" or "restrict" habitually to improve performance is as bad as unrolling your own loops or adding your own induction variables habitually for the same purpose.

      --
      Slashdot - News for Herds. Stuff that Splatters.
    114. Re:Clear Code by Explodo · · Score: 1

      Optimizations are on Maximize Speed. MSVC++ 6.0 is widely used, so these problems are relevant to many software engineers.

    115. Re:Clear Code by Nutria · · Score: 1

      In that case, the dumb ass should be moved to something else.

      Yeah, but getting a beauracracy to do something like that is difficult.

      --
      "I don't know, therefore Aliens" Wafflebox1
    116. Re:Clear Code by Anonymous Coward · · Score: 0

      I disagree slightly. For me, expressions with fewer negations are usually easier to understand. Therefore

      if (ptr == 0)

      is better than

      if (!ptr)

      And by the same token

      if (ptr)

      is preferable to

      if (ptr != 0)

      Your milage may vary.

    117. Re:Clear Code by David's+Boy+Toy · · Score: 1

      Now to confuse things more, personally I find if (!ptr) clearer than if (ptr == NULL)

    118. Re:Clear Code by Rei · · Score: 1

      The code is buggy, in that time(&first) may be catching the tail-end of a second. You need to loop first. I'll take care of that when transcribing your code. Also, your code is incomplete (I don't know what "GetLocationFromIndex" is; I'll just return its argument plus 1). I'll have to guess about a number of other things as well (maxX through Z - I'll assume they're defines; I'll assume const args where possible in passing, but that x, y, and z are passed by reference; and that location is a local variable in GetLocationFromIndex. I'll also standardize the microsoft-specific stuff - we'll use std::strings and cout for printing at the end.

      With no optimization in g++, I get that 10% difference - it takes a little over 5 minutes to run. With optimization? Zero seconds for both of them. The compiler apparently discovers that only the last run of each of them matter ;)

      Here's my unoptimized compilation line:
      g++ test.cxx -O0 -o test

      Here's my optimized compilation line:
      g++ test.cxx -O3 -funroll-loops -ffast-math -fno-math-errno -fmove-all-movables -frerun-loop-opt -o test

      Got a better example? :) This was too easy, and goes to show how powerful compiler optimizations are nowadays.

      --
      "Lock and load, Brides of Christ!"
    119. Re:Clear Code by Rei · · Score: 1

      Wait... your argument against inline is that it might mess up a poorly coded debugger, when debugging with optimizations on? Excuse me if I find that situation completely discountable in the real world. And your thing about inlining creating costs is that the compiler *weighs* the cost, and does so better than humans. If you jam all of your code into your inner loop, you're not giving it much of a choice, now are you? And the whole point is moot: you can always tell the compiler not to inline, and handle inlining yourself manually, if you think you're smarter than the compiler.

      --
      "Lock and load, Brides of Christ!"
    120. Re:Clear Code by exp(pi*sqrt(163)) · · Score: 1
      Use "const"
      Note that generally "const" isn't there for optimization. It's for safety. For example if you have a pointer to a const struct the compiler can't make the assumption that the object pointed to isn't going to change (through aliasing). It can only report an error if the programmer tries to use that particular pointer to change the data. There are some situations where const makes a difference but many programmers don't realize what those are.
      --
      Doesn't it make you feel good to know that our freedoms are protected by politicans, lawyers and journalists.
    121. Re:Clear Code by Explodo · · Score: 1

      My example was specific to MS VC++ 6.0, which is still widely used. It's an example that you cannot rely on optimizations in all compilers. The code was compiled in release mode with optimizations set to Maximize Speed. Often, developers in large projects have no control over the build settings and must optimize their own code.

    122. Re:Clear Code by Anonymous Coward · · Score: 0

      That is not applicable for event-driven code. If you're catching mouse events, you had better think about optimizing whatever you're doing with them ahead of time if you don't want sluggish behavior. E.g., if it involves disk or network IO, consider buffering the pertinent data to an ansyc I/O routine, or another thread.

    123. Re:Clear Code by David's+Boy+Toy · · Score: 1

      Of course if every software company worked that way, we'd have a few dozen programs in the world. The realities of super critical, and not so critical software is quite a bit different.

      Ask the customer if they want to pay 10 times more and wait 10 times longer for there software. If they do, then see if they write you a check, or just go buy the software that was written in a timely manner anyways :)

    124. Re:Clear Code by John+Hasler · · Score: 2, Interesting

      > There is a whole are of study involved in
      > correctness checking, which is related to
      > the SAT (Satisfiability) problem.

      Knuth:
      "Please don't assume that the above code is error-free. I have only proven it correct, not tested it." (or words to that effect)

      --
      Warning: this article may contain humor, sarcasm, parody, and perhaps even irony. Read at your own risk.
    125. Re:Clear Code by Anonymous+Brave+Guy · · Score: 1
      MSVC++ 6.0 is widely used

      Yet it still dates from the mid-90s, is two (soon to be three) major revisions behind the times, and was mostly written before the C++ standard was even finished. Optimisation technology has improved a little in the intervening decade or so, y'know!

      --
      If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
    126. Re:Clear Code by mrhartwig · · Score: 1

      Maybe the code-checking part of the article is relevant, but lots of the rest is obsolete. Particularly the part you chose to quote.

      The ferrite cores were replaced in the early 90s, when the computers were updated. The old computers were model AP-101, while the "new" are AP-101S. Faster CPUs, more & semiconductor memory, etc.

      http://en.wikipedia.org/wiki/AP-101 might help.

      The AP-101S's were delivered from the factory (IBM in Owego, NY) to NASA 4 or 5 years before they first flew. What took so long was all of that testing under discussion.

    127. Re:Clear Code by Anonymous+Brave+Guy · · Score: 1

      It's perfectly valid in that it will compile without requiring a diagnostic, but in any language I program that would parse it, it yields undefined behaviour. If you run that code and the object foo points to really is constant, that code is allowed to e-mail those dodgy pictures of your girlfriend to a lads' mag, reformat your hard drive, and then nuke the computer to destroy the evidence.

      --
      If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
    128. Re:Clear Code by Dwonis · · Score: 1

      I think that comment could be clearer. Are you commenting that the program, as it stands, will crash if no files are open, or that you've written some code to prevent the program from crashing if no files are open?

    129. Re:Clear Code by Anonymous Coward · · Score: 0

      if(!NotFlag!=!False);
      else{DoStuff()};

    130. Re:Clear Code by Com2Kid · · Score: 1

      Actually on a modern machine most of the time is spent waiting for the programmers asstacular code to finish loading up.

      Because odds are, some fucktard thought embedding all possible resolutions of images used by a program, into the program executable, uncompressed, was a good idea. ....

      Or some such stupid arsed thing.

      Oh, and the server performance loss thing? That is why 10 year old software on 10 year old machines runs comparable to modern kit, or at least the speed difference is not proportional to the increases in overall system speed and specifications that have occurred over the years.

    131. Re:Clear Code by drinkypoo · · Score: 1

      Yes, and sometimes it's time to use a digital copy instead of a hand-updated book. Occasionally you might print out the resulting code in a new book, and maybe call it a new major version.

      --
      "You're right," Fisheye says. "I should have set it on 'whip' or 'chop.'"
    132. Re:Clear Code by drinkypoo · · Score: 1

      It's all the warning they need, but it still doesn't help them understand why you did what you did. Believing that no one smarter than you should work on your code means one of two things; you are either incredibly arrogant, or wrote incredibly unmaintainable code. Either way, you should revise your expectations of the future, and write code that other people can work on. Unless it's the rare code that is never redistributed, you should go out of your way to comment it. Maybe in ten years, your way of thinking will have changed enough to where it will take you a long time to figure out what the hell you were thinking.

      --
      "You're right," Fisheye says. "I should have set it on 'whip' or 'chop.'"
    133. Re:Clear Code by Anonymous Coward · · Score: 0

      > Remember - compilers don't care about comments!

      Don't laugh. I actually worked with a programmer (still in school) who thought that writing comments and using clear variable names was a good idea because it helped the compiler "understand" the code better.

      Okay, now laugh.

    134. Re:Clear Code by Anonymous Coward · · Score: 0

      No disagreement expressed by your link, but it does suggest that the original poster wasn't a total moron using "since" in the original context.

    135. Re:Clear Code by zootm · · Score: 1

      Yes. Couldn't agree more. If your algorithm is sound, you're sorted - random systematic "optimisations" will be done by the compiler. Making your code unreadable or unsafe in the name of "efficiency" is crazy - 9999 times out of 10000, it won't make a damned difference to runtimes, it'll just make your code unreadable or unsafe. Algorithmic efficiency is where almost all efficiency that will still matter after compilation lies.

    136. Re:Clear Code by HopeOS · · Score: 1

      You brought up an interesting example and one that I use often. Someone recently pointed out a different order that apparently improves things a percent on some processors. Preload the cache by reading the first column. On a parallel pipeline processor, each read will stall waiting for main memory, but many of the reads will stall in parallel. Also, the whole cache line will be loaded which could be a substantial amount of the array depending. As the y/x loop finally begins, main memory will be arriving for future reads on upcoming rows.

      Personally, I have not put this to practice, but it was an interesting thought anyway.

      -Hope

    137. Re: Clear Code by gidds · · Score: 1
      Exactly.

      As Michael Jackson (the systems guru, not the singer...) put it:

      "The First Rule of Program Optimisation: Don't do it.

      "The Second Rule of Program Optimisation (for experts only): Don't do it yet."

      As Donald 'the next volume will be any decade now' Knuth said:
      "Premature optimisation is the root of all evil."

      And as W. A. Wulf put it:

      "More computing sins are committed in the name of efficiency (without necessarily achieving it) than for any other single reason -- including blind stupidity."
      Having seen a lot of code over the years, I think they might well have a point...

      --

      Ceterum censeo subscriptionem esse delendam.

    138. Re:Clear Code by lymc · · Score: 1

      In 1976 this wasn't a possibility, even for the likes of NASA. Or rather, I should say, for purposes of keeping a complete record, it was not a possibility.

    139. Re:Clear Code by omb · · Score: 1
      All this is very good sense; one thing you do need to know is that the compiler can-NOT change the algoithm, and that is sometimes KEY;

      as an earlier poster noted we are in th 99.98 - v 0.02 percent situation here:

      Spending time on the 99.98% of the code is a wase of time.

    140. Re:Clear Code by Impy+the+Impiuos+Imp · · Score: 1

      God damn, son. Just be glad they didn't open the box and see a Flintstones bird in there chisling away on a stone tablet.

      --
      (-1: Post disagrees with my already-settled worldview) is not a valid mod option.
    141. Re:Clear Code by Impy+the+Impiuos+Imp · · Score: 1

      He was being sarcastic, although, evidently, not obviously so. Of course banks don't throw away the COBOL -- it's stable, proven over years, and that is worth many billions in liability to the banking industry, so it's far cheaper to pay some company like Unisys to maintain ancient hardware indefinitely than to risk one multi-hundred million dollar fiasco due to new software.

      I worked on international funds transfer (SWIFT, if you've heard of it). They did shift their network to new hardware and software, but only after years of testing, and slow migration, ever so slow.

      Anyhoo, the poster was sarcastic, but you caught that, didn't you. Good post.

      --
      (-1: Post disagrees with my already-settled worldview) is not a valid mod option.
    142. Re:Clear Code by drinkypoo · · Score: 1

      What you're saying, however, is that it meant it was time to do a rewrite. What I'm saying is that it was time to reset the comments, and start a new log book. The old book becomes the historical document explaining how it got this way, and the new book tracks the new changes. Maybe I just don't understand what was in the book, what it was used for, or how it was used?

      --
      "You're right," Fisheye says. "I should have set it on 'whip' or 'chop.'"
    143. Re:Clear Code by Anonymous Coward · · Score: 0

      The latter code will only run 50 times faster if your arrays are stored in row major order. Moreover it's not clear to me which will be faster on a multi-processor system.

    144. Re:Clear Code by Anonymous Coward · · Score: 0
      I'm not a C++ programmer, but I do think that is a really neat construct, and all languages need to have something like that.

      One thing I sometimes hear people mumble about, whenever SMP and dual-core processors come up, is that people don't write enough parallelism into their software, so the recent hardware advances don't pay off too well.

      But if more people would use constructs like for_each() or otherwise use higher-level semantics than loops, then perhaps compilers could start doing things like processing every item in a sequence, in parallel. Sure, there are risks (locking issues, crappy OS's thread creation overhead, etc) but the payoff could be enormous.

    145. Re:Clear Code by Impy+the+Impiuos+Imp · · Score: 2, Insightful

      ==true and ==false can cause bugs if what you happen to be using isn't a C++ bool but some BOOL that's #defined as an int somewhere.

      Proper naming helps out here.

      Keep in mind people also follow other standards that say DON'T PUT CONSTANTS ON THE RIGHT in a Boolean expression.

      Hence instead of:

      if (!DeviceIsFunctioning)

      you get the "improved" crap of:

      if (false == DeviceIsFunctioning)

      where rules pile on each other to make things even less intelligible. Now throw in some Hugarian munging, and life is grand!

      --
      (-1: Post disagrees with my already-settled worldview) is not a valid mod option.
    146. Re:Clear Code by Impy+the+Impiuos+Imp · · Score: 1

      Umm, he was nitpicking meaning? Isn't that grammar?

      In any case, nitpicking nitpicking, he typo'd a missing space between "at" and "least", and should have used double quotes around his word examples rather than single.

      --
      (-1: Post disagrees with my already-settled worldview) is not a valid mod option.
    147. Re:Clear Code by Impy+the+Impiuos+Imp · · Score: 1

      > camelCaseIsThis (internal visibility)
      > PascalCaseIsThis (public visibility)

      camelToeIsThis (public visibility)

      --
      (-1: Post disagrees with my already-settled worldview) is not a valid mod option.
    148. Re:Clear Code by lymc · · Score: 1

      I guess that I'm saying that eventually code, reused and added to in even the most careful way, becomes more apt to failure than a rewrite would be. The original citing here was the example of the code written for the space shuttle, and how it has been reused through the years, even in the face of what has to be changing requirements. Yes, it works, and perhaps in man-rated tasks where safety is first, that's supremely important, but most computer programs aren't man-rated. Overstressing conservatism is not always the best way.

    149. Re:Clear Code by Kohath · · Score: 1

      After just writing the code and seeing if it's fast enough, and then after profiling the code and finding this is the slow section, then the correct way to optimize something like this is usually to find some pre-optimized libraries for processing an image (or a matrix, or whatever your data is) and just call the library functions.

    150. Re:Clear Code by Inthewire · · Score: 1

      How is it easy money if no one ever takes the bet?

      --


      Writers imply. Readers infer.
    151. Re:Clear Code by dubl-u · · Score: 1

      Much better is an explanation over a block of 5-10 lines giving you an idea of what you are trying to achieve. Comment any thing that is not clear, like if your using bitwise shifts to multiply and divide, for example.

      I used to write lots of explanations. I still do when I have to, but now it feels like a defeat to me.

      Instead, I try to make the code readable enough that it doesn't need explanations. E.g., I'll take each of those 5-10 line blocks and do an Extract Method refactoring. The information that would have ended up in the comment ends up in the method name, in the parameter names, and in the return variable name.

      Also, I put a lot of that energy into writing good unit tests. Comments can get out of date, but unit tests always tell the truth.

    152. Re:Clear Code by Anonymous Coward · · Score: 0

      Anyone who writes "== true" or its variations is missing the point. The point is that an if statement is choosing a flow of control based on a boolean expression. A boolean value is already boolean (duh) so you don't need to compare it to another boolean.

      I used to write the typical "if (!ptr)..." all the time, but over the past few years have switched completely to "if (ptr != NULL)". Or, in appropriate circumstances, "if (NULL == ptr)" in order to avoid the "==" vs. "=" typo. The "!" by itself is less visible and making an assumption about the values of ptr. Clarity really does have to come first.

    153. Re:Clear Code by Xyrus · · Score: 1

      Having worked with both embedded systems and PCs, here's my philosophy.

      The first rule of optimization is not to optimize. Get the damn thing working first. After you get it working, don't optimize. Test the damn thing to make sure it doesn't break. After testing, do not optimize. Profile the damn thing to find the choke points. After profiling your code, do not optimize. Analyze the damn profile to determine whether or not optimization will be worth the additional effort.

      Establish what you are trying to do, then do it and make sure it works. Once you have something that works you have a baseline to compare against when performing optimizations. You'll also have a much better idea of how long it will take to implement optimizations.

      I've seen far too many programmers spend days trying to optimize with incomplete code and doing little more than running around in circles (and not getting much more performance out of their code than what the compiler was doing).

      With embedded systems, you are more likely to get a decent performance boost from doing hand optimizations, but only if you fully understand the underlying hardware. You may write your super-leet optimized assembly routine, but if you end up shoving it into the wrong memory section you my find your code runs a hundred times slower.

      In general, compilers have come a long way and do a decent job of optimizing most code pretty good.

      With embedded systems, that's a little more shakey. I always write some test code and compile to assembler to see if there is anything obviously bad about what the compiler is doing.

      So for PC's and the like, I have more faith in the compiler. With embedded systems, I have faith in the compiler...after inspection. :)

      ~X~

      --
      ~X~
    154. Re:Clear Code by earthforce_1 · · Score: 1

      Actually, inline code can be slower than a function call, since a frequently called function will hit on the cache. Repeated inline code will miss, because the the repeated sequences occur at different addresses. The penalties for a cache miss can sometimes be much higher than the overhead for a function call.

      --
      My rights don't need management.
    155. Re:Clear Code by Xyrus · · Score: 1

      That's not the best advice.

      It's far better to get the code working first, then go back and analyze where optimizations will be most useful. Most trivial optimizations will be handled by the compiler.

      There are some things you can do along the way to help performance, but the serious "thinking" optimizations should come after you have a solid base to work from.

      ~X~

      --
      ~X~
    156. Re:Clear Code by Rei · · Score: 1

      Yep - which is why it's wise to leave whether or not to inline code up to the compiler ;)

      --
      "Lock and load, Brides of Christ!"
    157. Re:Clear Code by drinkypoo · · Score: 1

      Granted there comes a time when the code becomes unmaintainable, but from the description this is a case of the media the code is stored on becoming impossible to update... it's almost like a worn-out flash memory or something :) It sounds like the problem was the process, not the program.

      --
      "You're right," Fisheye says. "I should have set it on 'whip' or 'chop.'"
    158. Re:Clear Code by Citizen+of+Earth · · Score: 1

      There is a whole are of study involved in correctness checking, which is related to the SAT (Satisfiability) problem.

      The problem that I see with these formal methods is that the proof that a program is correct is more complicated than the program itself. How do you prove that the proof is correct? Another, larger proof?

      Of course, in constructing a complete formal proof, you are implementing the program twice and scrutinizing it very closely, which is probably where the major benefit comes from, if you can affort the cost.

    159. Re:Clear Code by jonored · · Score: 1

      It seems worthwhile to note that if I recall, one of the reasons for the old, bigger-component hardware has to do with size being related to radiation resistance; take, say, a P4 and throw it into a nice radiation bath - say, outside of the atmosphere - and I'd not be surprised if it wouldn't run a thing, and I certainly wouldn't trust it with my life.
      That said, it certainly doesn't preclude newer, better technology for the shuttles, it just means that they have significantly different design requirements physically, in addition to the strict software requirements. And I'd certainly like to have the multiply-redundant systems to keep a stray gamma ray from killing me by flipping a bit in the wrong place.

      So basically, old hardware is, and new hardware must be, more radiation resistant than our fast land-based new systems - and this leaves everyone with much less incentive to make new technology for the purpose, especially with the old stuff functioning for the most part just fine.

    160. Re:Clear Code by Anonymous Coward · · Score: 0

      OK. 1. The Linux development model has been proven for over 5000 years. The model is good (better than the ultra-reliable group's). The Linux model has continuous peer-review and re-review. It isn't code-checked by one group, but by thousands of different groups, all running different (but sometimes overlapping) tests. There are also automated code checkers (40 million lines of software is more than 400,000). 2. The device drivers aren't 'exactly' in the Linux kernel. They are seperated out. When you compile a linux kernel, you can have drivers in the kernel, but usually 'drivers' are built as loadable kernel modules. The 'driver' can be swapped in and out as needed (it's permanently swapped in if it's compiled in, which is mandatory if people want real time linux). Linus recieved an award from the ACM for his work on loadable kernel modules. When the engineers did jet engine testing for the Joint Strike Fighter aircraft, they found that Linux performed more reliably, and at a higher level of performance than any other software they had used (full environmental engine test stand operation and data monitoring). The US Navy and Air Force similarly have had no problems. Nor have the Livermore 'Nuclear Simulation' supercomputers. The Linux kernel might not be as closely watched as this code, but it's a damn site closer than (ANY) software you've ever seen or used.

    161. Re:Clear Code by Anonymous Coward · · Score: 0

      Bullshit! Cobol is slow as hell (nearly as bad as Java). C can be optimized right down to assembly (and if there is any doubt, you put inline assembly into C). The original COBOL development group (include Grace Hopper) were gathered together years after. They said that the entire 6 weeks they spent working on the language was productive, but they only expected the language to be a 'throwaway' language. If they had known that silly business people would grab onto it (because they could almost understand what was going on with the verboseness of the language), they would have spent more time fixing some of the glaring problems with the language. It's a 50 year old language. Man can you tell!

    162. Re:Clear Code by BobNET · · Score: 1

      How do you prove that the proof is correct? Another, larger proof?

      A proof is a proof. What kind of a proof? It's a proof. A proof is a proof. And when you have a good proof, it's because it's proven.

    163. Re:Clear Code by ajs · · Score: 1

      While not truly an algorithmic optimization, the old Apollo compilers got in some hot water with benchmarkers by recognizing when input code was identical to certain library functions, and substituting a call to the library code. One benchmark ran something like 100 times faster on Apollos than it did on Suns. Persoanlly, I thought it was valid, since it was a generic optimization that would have helped real user code (I think they were specifically replacing FFTs with a hand-tuned assembly version).

    164. Re:Clear Code by Just+Some+Guy · · Score: 1
      well the first thing to optimize is the algorithm.

      Amen. I was playing around with a cheesy sieve prime test a little while ago just for nostalgia's sake, and had a line like:

      maxtest = sqrt(testvalue)
      if candidate > maxtest:
      ..return 1
      I realized that I didn't care a bit about an exact value of sqrt, and that the value in testvalue was incrementing by two each time, so I wrote an integer-based replacement that worked like this:
      maxsqrt=4
      sqrtvalue=2

      def isqrt(value):
      ..global maxsqrt, sqrtvalue
      ..if value <= maxsqrt:
      ....return sqrtvalue
      ..else:
      ....sqrtvalue += 1
      ....maxsqrt = value * value
      I shaved about 60% off my runtime by understanding that I never really wanted to compute an accurate value, and could use the nature of the input set to replace the original "simple" function with a more complex, tailored one that ran orders of magnitude faster. No machine will do that for you in the near future.
      --
      Dewey, what part of this looks like authorities should be involved?
    165. Re:Clear Code by MerlinTheWizard · · Score: 1

      This is a very good point. Anyway, the guy who thinks that every single path of code has to be proven by the developer in some critical environment settings is just daydreaming. It doesn't work this way. And as Knuth insightfully says, it can't even work. If engineers were really required to do this, nothing would get accomplished at all, or very little. And all the proofs would just guarantee that something has been overlooked anyway - and that it will fail at some point. Proper, intensive testing is the only way to go. And certainly not by the same people that wrote the code. That won't work either. This is also why I think a developer's proof on their own code wouldn't be worth much. You can't be on both sides. Granted mathematicians do this, but this is very different: they usually don't have any real time constraint, most of their work is not "practical" in any way and last but not least, their work has to be peer reviewed a lot before being validated. This is how it works in the academic world. It can't work this way in the industrial world, because obviously it would take too much time and it would pose IP issues as well. Open source is a bit like this - but the day when safety-critical, commercial devices will be open-sourced for the good of all is still very, very far away.

    166. Re:Clear Code by Anonymous Coward · · Score: 0

      Sometimes new is better, even if it is painful.

      Sometimes, but usually not, there is a reason that tons of changes are made. Errors are fixed, new features added, special cases handled. All that (with the possible exception of new features) has to be redone from scratch, usually by people that don't understand why all this wierd stuff is in the code, when you start over. Total rewrites of working systems are generally bad, but I didn't really learn that until I had done some.

    167. Re:Clear Code by Anonymous Coward · · Score: 0

      -Werror is a pain. Some of the warnings that gcc generates really are non-warnings.

      One example in particular, sometimes gcc will generate warnings on different platforms which really should not be. For instance, let's say there's a function that takes a const char * arg. You port your program to a commercial Unix box where some of the headers might pre-date the usage of const pointers in C. So, as declared in the header, the function takes char * instead of const char *. And even though said function doesn't modify the buffer, GCC doesn't know that. So let's say you pass it a string literal. It gives a warning. A warning that doesn't really mean anything at all. Quite harmless.

      But wait. You called gcc with -Werror. So this silly warning (which really shouldn't exist) makes your project fail to build.

    168. Re:Clear Code by jmv · · Score: 1

      Of course, it depends on the CPU, the exact size and the operations performed, but I really doubt you can find a case where where 1 is 50 times faster. If you use prefetch carefully, bath can actually be completely equivalent.

    169. Re:Clear Code by cerberusss · · Score: 1
      writing clear and easy to understand code is more important

      Are you KIDDING?? It was hard to write, it should be hard to read!!

      --
      8 of 13 people found this answer helpful. Did you?
    170. Re:Clear Code by Citizen+of+Earth · · Score: 1

      A proof is a proof. What kind of a proof? It's a proof. A proof is a proof. And when you have a good proof, it's because it's proven.

      Um, proofs are susceptible to mistakes just like anything else. Ask a mathematics professor or assignment grader. Ask a referee for a research journal if they receive research papers with proofs that have mistakes in them. One could argue that the program itself is a proof that it solves the problem that it is supposed to solve.

    171. Re:Clear Code by drgonzo59 · · Score: 1
      If it's the program that flies the Shuttles or flies people every day from coast to coast it can and should be proved to work for every possible code path and not lead to failure or be in some unpredictable (unexpected state).

      This is not done by hand obviously, 10 independent if statements is already 1024 cases to check. There are ways to automate it to a certain degree (obviously first there is a proof by hand that the automated checker is always correct). Also there are ways to take shortcuts, because for example not all branches are independent from each other, part of the programs are modular, and there are way to reduce the boolean logic to simpler forms.

      The point was that you can't have regular Linux or Doom III code and submit it for such kind of testing, the programmer has to write it in a very different way just to facilitate make it pass the qa/qc. So instead of having 4 nested 'if's each with 3 disjunctions and conjunctions in the condition, maybe be it is possible to write them in a sequential way, that kind of stuff.

    172. Re:Clear Code by shutdown+-p+now · · Score: 1
      Write code that is easy to understand and modify, then optimize it, but only after you have profiled it to find out where optimization will actually matter.
      How true! One other important rule which is follows from yours is: "Never write in C that which can be written in Lisp/Python/Ruby/etc"
    173. Re:Clear Code by drgonzo59 · · Score: 1

      Well, obviously the correctness proof checker would have to be checked by hand. Well, the problem though is that it is 'ok' to make a mistake on someone's test or even when submitting a publication to a journal, compared to when a 747 blows up in flames over Kansas killing hundreds of people.
      But you are right, even FAA has limits on how many crashes due to software it allows for so many flight hours. I think it is in the tens or hundreds of millions of flight hours. So if in that periods a plane crashes and burns killing everyone on board, that would be acceptable. For practical purpuses you might as well say it is 'never' allowed to happen. That is why the program and the team that does the testing probably consume just as much or even more resources than the actual team that writes the code. It cannot be the same team, technically, as someone mentioned in a post above.

    174. Re:Clear Code by zonker · · Score: 0

      most banks may run ancient code but the hardware is typically fairly recent (though often based on old technology).

      i worked for a bank that used as/400's which are based on old tech (but so are todays pc's) and they ran fairly old code. however the machines aren't ancient by any means. those types of machines are designed with this issue in mind and typically don't suffer from upgrade woes as they are highly backwards compatible (this is also an advantage of high level languages).

      for instance when the bank decided to upgrade the as/400's from the older cisc based to 64bit risc based the upgrade went without a hitch. in fact the code recompiled on first launch, automatically...

    175. Re:Clear Code by Thangodin · · Score: 1

      Yes, but if they don't understand 'if (!ptr)', what will they understand? And if they don't understand it, they have no business touching the code.

      Personally, I'll take properly objectified and commented code over 'clear' unoptimized code any day. If you're writing business apps, you may not need the extra cycles, so you can write a formula the way it would look in a math textbook. In game programming. almost nothing will come out looking that way. Formulas get broken down so that the inner loop does only what it absolutely needs to--and that's a simple example. More often than not, the algorithm is itself based on some bizarre mathematical hack from one of the Gems books. This is why dev editors now recognize web links...

      My present pet peeve is badly designed objects. I shouldn't have to know the implementation details of a class and half a dozen associated classes in order to call one method. Hide that crap--that's what objects are for! If I have to duplicate all the effort someone put into writing the class every time I go to use it, I might as well write my own, so why are we paying them?

      And dammit, if someone is going to specify a long list of complex arguments, the least they can do is put something in the header to describe what those arguments are and how they're used. Mind you, if the coupling is that strong, it usually means your object is broken, and it's time to refactor.

    176. Re:Clear Code by severoon · · Score: 1

      It's because it's easy money that no one ever takes the bet. Get it? In other words, it would be easy money.

      --
      but have you considered the following argument: shut up.
    177. Re:Clear Code by Jamu · · Score: 1

      Both operate on the data in a serial manner and therefore the order of execution of the code inside the loops may be important. Any compiler making the optimization would have to check for this.

      --
      Who ordered that?
    178. Re:Clear Code by ByteSlicer · · Score: 1

      Theres a semi-colon after the if, so the else will be illegal...

    179. Re:Clear Code by aug24 · · Score: 1

      Given that symbolically the two snippets are identical, I take it you are referring to a *structure* that has some *quality* to be taken advantage of?

      In other words that 'thing[][]' should be looped on the interior array first?

      If that's not what you mean, then I would suspect you may be mistaken, but would love to hear more...?

      J.

      --
      You're only jealous cos the little penguins are talking to me.
    180. Re:Clear Code by Anonymous Coward · · Score: 0

      Oh the irony that you can go suck my big American fuckstick, fuckstick.

    181. Re:Clear Code by maxwell+demon · · Score: 1
      it's slow

      Funny that you give a link to fastcompany.com, then! :-)
      --
      The Tao of math: The numbers you can count are not the real numbers.
    182. Re:Clear Code by siokaos · · Score: 1

      This clearly depends on the width to height ratio. Where do you get 50?

      --
      http://siokaos.org/
    183. Re:Clear Code by DrSkwid · · Score: 1

      Sounds like the halting problem to me.

      --
      There are places where the networks are not touching,and there are places where they are-Boeing's Lori Gunter
    184. Re:Clear Code by cedspam · · Score: 1

      just consider the code for the airbus a320 series:
      redundant computers, with differents cpu language and programmer teams, checks the sanity of commends send to the fly by wire(vote system).
      they have not only to avoid bugs, but most of all avoid making the same bug than the others.

    185. Re:Clear Code by ControlFreal · · Score: 1

      Algorithmical optimization makes the most difference.

      Amen. The higher the level of abstraction at which you optimise the algorithm, the better. I will always remember a difficult algebra-related problem I was working on for my research. For the record, that was a weighting problem of some kind.

      Given the problem at hand, the most accurate way to do this would be to use a QR factorization, which is about O(n^3). In fact, the QR is suggested in all textbooks, because of its excellent error-propagation and numerical condition properties.

      However, given the particular type of data for the particular problem at hand, it turned out that a Cholesky factorization ---even though it's normally discouraged because of its numerical properties--- was more than accurate enough. And a Cholesky is O(n^2) rather than O(n^3).

      Previously, I had thrown all kinds of optimization at the problem (using the ATLAS libraries, all kinds of other stuff), which did cut calculation time by a factor of 5. However, the high-level realization that for the particular problem at hand, accuracy wasn't much of an issue, cut the time for big problems by a factor of 100 or more.

      So indeed. Optimize your algorithm, as high up in the conceptual framework as possible.

      --
      Support a Europe-related section on Slashdot!
    186. Re:Clear Code by Anonymous Coward · · Score: 0

      The parent forgot to mention that he's accessing the array as array[y][x]. Actually this is a good catch, as array[x][y] would probably seem more natural to some folks..

    187. Re:Clear Code by Anonymous Coward · · Score: 0

      Eh, Cholesky is O(n^3). ((2n^3)/3 I recall). QR has a larger coefficient though, and Cholesky requires the matrix to be positive semidefinite.

    188. Re:Clear Code by Anonymous Coward · · Score: 0

      And you're missing the fact that in C it's natural to deal with pointers as if they were booleans.

    189. Re:Clear Code by Anonymous Coward · · Score: 0

      Will the compiler optimize the first piece of code to look like the second? Probably not (tell me if I'm wrong)

      gcc-4.0 will be able to optimize this under certain circumstances, gcc-3.x won't.

    190. Re:Clear Code by Anonymous Coward · · Score: 0

      A more-concise, and potentially more clear solution would be: for_each(foo.begin(), foo.end(), ...).

      Not really, in the cols vs rows xample, if the object 'knows' how to traverse itself, what you are doing is just eliminating one of the possibilities, there's a high price in that encapsulation.

    191. Re:Clear Code by oliverthered · · Score: 1

      Well, use cast. telling you that you should or shout not be using a CONSTANT value is very important.

      Sending a const to a non const function is dangerous, since that function has 'stated' that it intends to modify the value.

      On the same note (but not so critical), your not guaranteeing that a char * is going to be constant so sending it to a function that required a constant throughout it's execution is also important.

      I'm not using old headers or an old compiler.
      Either fix the headers, cast, pragma a message or whatever. just make the thing compile with -Werror so that when the application code accidental sends a char * to a const char * function my compiler chokes, it may be that the functions threaded and synchronisation is missing.
      With sony are starting to make 4.5 gen systems (8+processors) as games consoles, 40+ processors on a desktop looks promising and I would expect your code to be thread safe *cough* QT/Troltech *cough*

      --
      thank God the internet isn't a human right.
    192. Re:Clear Code by Salamander · · Score: 1
      Excuse me if I find that situation completely discountable in the real world.

      Are you saying such "poorly coded" debuggers don't exist? Anybody who actually does any real programming knows that they do and that people are often stuck with them for other reasons (e.g. their being the only supported option on a platform they use). Maybe it's convenient for you to discount that, but it's not very rational.

      And your thing about inlining creating costs is that the compiler *weighs* the cost, and does so better than humans.

      Actually it doesn't. It can't possibly know how often an inline function is used in a large set of separately-compiled modules, let alone what effect the duplication might have on caches, and it can't undo the inlining when they're linked together if it guessed wrong. Compilers can make many decisions better than humans, but not - or at least not always - this one. Learn something about how compilers and computer systems work below the JavaScript level before you make your next claim about optimization.

      --
      Slashdot - News for Herds. Stuff that Splatters.
    193. Re:Clear Code by Illume · · Score: 1

      The first one hits memory sequentially, which is good for caching as each cache line stores a large chunk of sequential memory.

      A sequential access has the disadvantage that modern CPUs can't fill the L2 cache efficiently.

      An AthlonXP will cache a 64 byte block of data when you read the first bytes. If you access your data in sequence your code will have to wait for every memory access. Your second loop can be faster on such systems, because more data will be waiting in the cache before you access it.

      When you're optimizing never assume that something will be faster. Allways examine a simple solution on your target platform(s), it might already be quite efficient.

    194. Re:Clear Code by Alsee · · Score: 1

      I just double checked and it seems to work fine for me compiling C with GCC.

      -

      --
      - - You can't take something off the Internet! That's like trying to take pee out of a swimming pool.
    195. Re:Clear Code by MerlinTheWizard · · Score: 1

      You're right about code complexity. Generally speaking, it's an almost obvious matter of fact that the less complex your code is, the less prone it is to errors.

      That being said, you're talking about automated testing. This is also what I was referring to earlier. But automated testing is not a formal proof.

      Cutting on code complexity is a double-edged sword though. Usually (but not always), the less complex your code, the less efficient and the bigger it tends to get. If you want to keep it simple, you have to make a lot of trade-offs.

      The critical parts of your code should always be totally independent, self-sufficient, as much as possible. This is what makes it easy to test and validate.

    196. Re:Clear Code by ByteSlicer · · Score: 1

      My bad. That code was playing tricks with my eyes. I didn't notice that the statement after the if isn't there (and thus the ; is the empty statement). So basically it is just an extra negation of the condition of the if().

    197. Re:Clear Code by Anonymous Coward · · Score: 0

      "g++ test.cxx -O3 -funroll-loops -ffast-math -fno-math-errno -fmove-all-movables -frerun-loop-opt -o test"

      You forgot -fbreak-important-code :/

    198. Re:Clear Code by budgenator · · Score: 1

      The intersting part about ferrite core memory is that they don't change state when power-fails or even a random alpha particle strike.

      --
      Apocalypse Cancelled, Sorry, No Ticket Refunds
    199. Re:Clear Code by Anonymous Coward · · Score: 0

      Did you miss the point of my post? Yes, I know it is important to have the const there. Old header files don't.

      Have you ever compiled anything for those systems? You would know what I'm talking about. I can take a perfectly valid C program that uses APIs 100% correctly, move it to Solaris or HP-UX or Windows, and it'd spew spurious warnings due to things like this. Why the hell should I cast const pointers to non-const to make up for broken system headers?

      It's nothing to due with the problem of an "old compiler" as you suggest. It's a case gcc being more cautious than the original system.

    200. Re:Clear Code by Anonymous Coward · · Score: 0

      While my knee jerk reaction is to agree, one thing that coders have always been able to rely on is "it's ok if it's a bit slow, tomorrow's hardware will run twice as fast".

      Coders, and those who pass as software engineers may find that the free lunch is over. If you want a program to do twice as much, you'll have fewer options. You'll have to start using "tricks" to cut down on code size, or you'll have to use "tricks" to divide up the code into "N-way" code to take advantage of multi-threaded, multi-core processors.

      Code clarity _may_ start suffering as more programs hit resource barriers.

    201. Re:Clear Code by CaptKilljoy · · Score: 1
      "if (!ptr)" translates perfectly clear into english as "if no (valid) pointer" while "if (ptr==NULL)" involves some spurious special case value that I need to spend extra tinkering with.

      A null pointer doth not point to a 0 of any type, despite some blasphemous old code which impiously assumes this.
      --From "The Ten Commandments for C Programmers"
    202. Re:Clear Code by oliverthered · · Score: 1

      gcc is warning you of a potential error,
      If you really need to compile the code and don't are that your old headers may be dangerous then take off the -Werror flag and compile, or fix the headers, don't use it as an excuse for my new headers and new gcc not compiling a fresh build of xyz.

      --
      thank God the internet isn't a human right.
    203. Re:Clear Code by Anonymous Coward · · Score: 0

      Bullshit! Cobol is slow as hell (nearly as bad as Java).

      Bollocks. You know, there are two reasons why major financial institutions are not only maintaining their current COBOL codebases but writing new COBOL code. The first is that it would cost a lot of money to switch to a different language. The second is that COBOL is fucking fast for data processing.

      It's a horrible language, sure. But that doesn't make it slow.

      C can be optimized right down to assembly (and if there is any doubt, you put inline assembly into C).

      ROFL! You don't have a fucking clue what you're blathering about, do you? "Optimized down to assembly"? What the fuck is that meant to mean? That the language is compiled via assembly? All that means is that there's an extra step in the compilation process. The fact that C is conventionally transformed to assembly which is then transformed to machine code is IRRELEVANT. Try gcc -O0 -S, and look at the assembly that generates. Ooh, it's assembly! But that doesn't mean it's fast, fuckwit.

      That you can embed assembly in it? Also irrelevant. You can call assembly routines from COBOL if you want to. That doesn't affect the language itself. Which is fast. Because it's not much higher-level than assembly. Like FORTRAN. Which is also fast. In case you didn't know. Which, given your apparent complete lack of the first vestige of a clue where programming matters are concerned, I have to consider likely.

      It's a 50 year old language.

      Yeah? So is the C you enjoy wanking over so much. So is Lisp, which despite being 50 years old is so avanced that the mainstream still hasn't caught up. So, indeed, is the concept of assembly language. Age is irrelevant, asshole.

    204. Re:Clear Code by Anonymous Coward · · Score: 0

      I remember hearing about a c compiler that was very efficient at optimizing code. The company was doing some tests with the compiler on a VAX 11/780 and they had several compilers to test. They used a standard code source to run various loops and other things. They would start the timer after starting the program and stop the timer when the command prompt came back. Well, the other compilers were pretty close in their times except for one that would always come back to the prompt almost instantly. They decided to recompiled the programs with assembly output and compare the programs. The one fast compiler put out the assembly code of main(){}. The called the compiler company about this and the tech support asked these questions: Does it have any input? "no" was the answer. Does it have any output? "no" was the answer. Well, then what difference does it make what the program does. The compiler optimized out the entire program! They redid the test with a printf() call at the start and end of the main() function and got more accurate results.

      That's one smart compiler!

    205. Re:Clear Code by DJStealth · · Score: 1

      Sorry, I should have mentioned this, the caching issue isn't inherently with the loops, it's with the fact that I'm accessing data as array[y][x]. With the consecutively stored data being accessed via the inside loop.

    206. Re:Clear Code by DJStealth · · Score: 1

      It's interesting that gcc 4.0 will do this. I wonder what happens if I actually NEED the loop to access code the way which happens to be slower? I brought up this example, because there may actually be cases where you want to do some sort of process on an image in the y dimension first, such an optimization would break the code.

    207. Re:Clear Code by say · · Score: 1

      Yes, there is a difference. If you do a recursive faculty function, like this pseudo:

      FUNCTION faculty (int n)
      IF (n == 1)
      RETURN 1
      ELSE
      RETURN faculty(n - 1) * n
      END faculty

      If your compiler does that, for instance for n=5, after spinning down to 1, your stack would contain:

      return (5 * (4 * (3 * (2 * (1)))))

      While this isn't abysmal, it could be simplified to:

      FUNCTION faculty_iter (int n, int count, int sum_so_far)
      IF (count > n)
      RETURN sum_so_far
      ELSE
      faculty_iter (n, count + 1, count * sum_so_far)
      END faculty_iter

      Which is faster in most processors, because it resolves to extremely less nested function calls - just 1! This is due to the fact that the function is not part of an expression in the return call - and we don't need to know the value of the next recursion before we can compute the return value of the previous (because it has no return value!).

      Not very noticable in such a simple function, but when computing 1500! it matters.

      --
      Roses are #FF0000, violets are #0000FF, all my base are belong to you
    208. Re:Clear Code by AnfieldSierra · · Score: 1

      Jesus wept. Are you serious ? 50 times faster due to "caching" ??? Can I have some of what you're smoking please. Caching of what by whom ?

      You're spouting complete bullshit. Replace "x" with "q", "y" with "p", "width" with "foo" and "height" with "bar" and look again. These things are just variables!! Width and height only have meaning to you, not the compiler. I pray that no-one takes your post seriously as you clearly have no idea what you're talking about. The compiler might produce faster code with "loop unrolling" enabled but that really depends on the values of foo and bar and what code is within the body of the loop.

      Of course the compiler won't optimise the 1st snippet to make it look like the second. Shame on you for even considering that preposterous notion. Simply raising the issue deomnstrates a lack of understanding about the whole subject matter.

      As for it being less clear...I despair. There aren't ANY comments and there's nothing to indicate what difference each loop index makes!!

      I've had 15 years experience writing in C and you've had someone mod your post "insightful". Looks like more than the average quota of morons is moderating today.

    209. Re:Clear Code by Anonymous Coward · · Score: 0
      Jesus wept. Are you serious ? 50 times faster due to "caching" ??? Can I have some of what you're smoking please. Caching of what by whom ?

      You're spouting complete bullshit. Replace "x" with "q", "y" with "p", "width" with "foo" and "height" with "bar" and look again. These things are just variables!! Width and height only have meaning to you, not the compiler. I pray that no-one takes your post seriously as you clearly have no idea what you're talking about. The compiler might produce faster code with "loop unrolling" enabled but that really depends on the values of foo and bar and what code is within the body of the loop.

      You may have a point, but please take time to *think* about what the poster is trying to say before you fire off your reply.

      In this case, though the parent didn't specify the code that uses x and y, he did say it was a 2-D array.

      Now imagine what the CPU will do with:
      array[y][x], array[y+1][x], array[y+2][x] ... array[y+n][x]

      Versus:
      array[y][x], array[y][x+1], array[y][x+2] ... array[y][x+n]

      C arrays store elements of the last dimension in sequence in memory. There's a good chance that the next x (column) location will already be in the CPU data cache as you iterate through it. Jumping to the next *row* of the array (depending on the dimension) for each iteration of the loop could take considerably longer. I believe that's what he was trying to say.

  4. You should always... by Anonymous Coward · · Score: 5, Funny

    Optimize. Using cryptic, short variable names also shaves valuable microseconds off compile time and run time.

    1. Re:You should always... by FyRE666 · · Score: 4, Funny

      ... and by god don't let me see anyone using comments - comments are the devil's alphabet soup! Every programmer worth his/her salt knows that source code is self documenting...

    2. Re:You should always... by mjc_w · · Score: 1

      Yeah, right!

      And if you don't use variable names at all, it's even better!

      --
      This is the Constitution.This is the Constitution under the Bush administration. Any questions?
    3. Re:You should always... by MillionthMonkey · · Score: 4, Funny

      But the code compiles so much faster when you turn it all into comments.

    4. Re:You should always... by holle2 · · Score: 3, Funny
      Found on The Daily WTF http://thedailywtf.com/ShowPost.aspx?PostID=30233
      ------------
      [...]
      $result = mysql_query("SELECT a, b, c, d, e, f, g, h, i, j, k, l,
      m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2,
      h2, i2, j2, k2, l2, m2, n2, o2, p2, q2, r2, s2, t2, u2, v2, w2, x2, y2, z2,
      a3, b3, c3, d3, e3, f3, g3, h3, i3, j3, k3, l3, m3, n3, o3, p3, q3, r3, s3,
      t3, u3, v3, w3, x3, y3, z3, a4, b4, c4, d4, e4, f4, g4, h4, i4, j4, k4, l4,
      m4, n4, o4, p4, q4, r4, s4, t4, u4, v4, w4, x4, y4, z4, a5, b5, c5, d5, e5,
      f5, g5, h5, i5, j5, k5, l5, m5, n5, o5, p5, q5, r5, s5, t5, u5, v5, w5, x5, y5, z5,
      a6, b6, c6, d6, e6, f6, g6, h6, i6, j6, k6, l6, m6, n6, o6, p6, q6, r6, s6, t6, u6, v6, w6, x6, y6, z6,
      a7, b7, c7, d7, e7, f7, g7, h7, i7, j7, k7, l7, m7, n7, o7, p7, q7, r7, s7, t7, u7, v7, w7, x7, y7, z7,
      a8, b8, c8, d8, e8, f8, g8, h8, i8, j8, k8, l8, m8, n8, o8, p8, q8, r8, s8, t8, u8, v8, w8, x8, y8, z8,
      a9, b9, c9, d9, e9, f9, g9, h9, i9, j9, j9, casenum, contype
      FROM gct WHERE casenum = '$aid'");
      while(list($a,$b,$c,$d,$e,$f,$g,$h,$i,$j,$k,$l,
      $m,$n,$o,$p,$q,$r,$s,$t,$u,$v,$w,$x,$y,$z,$a2,$b2, $c2,$d2,$e2,$f2,$g2,
      $h2,$i2,$j2,$k2,$l2,$m2,$n2,$o2,$p2,$q2,$r2,$s2,$t 2,$u2,$v2,$w2,$x2,$y2,$z2,
      $a3,$b3,$c3,$d3,$e3,$f3,$g3,$h3,$i3,$j3,$k3,$l3,$m 3,$n3,$o3,$p3,$q3,$r3,$s3,
      $t3,$u3,$v3,$w3,$x3,$y3,$z3,$a4,$b4,$c4,$d4,$e4,$f 4,$g4,$h4,$i4,$j4,$k4,$l4,
      $m4,$n4,$o4,$p4,$q4,$r4,$s4,$t4,$u4,$v4,$w4,$x4,$y 4,$z4,$a5,$b5,$c5,$d5,$e5,
      $f5,$g5,$h5,$i5,$j5,$k5,$l5,$m5,$n5,$o5,$p5,$q5,$r 5,$s5,$t5,$u5,$v5,$w5,$x5,
      $y5,$z5,$a6,$b6,$c6,$d6,$e6,$f6,$g6,$h6,$i6,$j6,$k 6,$l6,$m6,$n6,$o6,$p6,$q6,
      $r6,$s6,$t6,$u6,$v6,$w6,$x6,$y6,$z6,$a7,$b7,$c7,$d 7,$e7,$f7,$g7,$h7,$i7,$j7,
      $k7,$l7,$m7,$n7,$o7,$p7,$q7,$r7,$s7,$t7,$u7,$v7,$w 7,$x7,$y7,$z7,$a8,$b8,$c8,
      $d8,$e8,$f8,$g8,$h8,$i8,$j8,$k8,$l8,$m8,$n8,$o8,$p 8,$q8,$r8,$s8,$t8,$u8,$v8,
      $w8,$x8,$y8,$z8,$a9,$b9,$c9,$d9,$e9,$f9,$g9,$h9,$i 9,$j9,$j9,$casenum,$contype) = mysql_fetch_row($result))
      [...]
      ------------
    5. Re:You should always... by prostoalex · · Score: 1

      And when choosing letters and numbers for variables, choose the ones that take the fewer pixels on the screen, like i, l, _i_, __i, ____i, i1, _i1. This will shave a few seconds off your graphical card processing and will lower your power bill, since there're fewer bytes traveling between mother board and graphics card.

    6. Re:You should always... by Anonymous Coward · · Score: 0

      What nutcase to a moderator modded that insightful... lol

      The BOFH? :-)

    7. Re:You should always... by Peter+Cooper · · Score: 1

      With some languages and some frameworks, you're right.

    8. Re:You should always... by lbmouse · · Score: 1

      Comments are for wusses. I like to live dangerously!

    9. Re:You should always... by johndiii · · Score: 1

      For maximum efficiency, you should always use black text on a black background. You should know your code well enough that you don't have to re-read it!

      --
      Floating face-down in a river of regret...and thoughts of you...
    10. Re:You should always... by aixguru1 · · Score: 2, Interesting

      A good programmer who codes in C should be able to understand what is going on. Still it is no substitute for real documentation... Someone should let the folks that enter the IOCCC that they have some of the worst self documenting code I have seen though. It's like trying to read the Xlib programming manuals after a few to many drinks (not recommended and may result in a nasty hangover in the morning).

      --
      root 10956 5164 0 Oct 22 - 0:23 sendmail: rejecting connections: load average: 70 (isn't sendmail just too kind)
    11. Re:You should always... by slavemowgli · · Score: 1

      Not just that - you never know whether the compiler you're using is advanced enough to optimize away comments!

      --
      quidquid latine dictum sit altum videtur.
    12. Re:You should always... by PiGuy · · Score: 1

      Believe it or not, back in the days of Applesoft BASIC (for the Apple II line of computers), code with short variable names and no comments ran faster. This stems from the fact that the code was interpreted directly, without an intermediate bytecode state.

    13. Re:You should always... by WindBourne · · Score: 4, Funny

      Sadly, some will even work better.

      --
      I prefer the "u" in honour as it seems to be missing these days.
    14. Re:You should always... by ron_ivi · · Score: 4, Informative
      Using cryptic, short variable names also shaves valuable microseconds off compile time and run time.

      There's nothing wrong with short variable names.

      Thus quoth Linus in the Linux Coding Style guide.

      Chapter 3: Naming

      C is a Spartan language, and so should your naming be. Unlike Modula-2
      and Pascal programmers, C programmers do not use cute names like
      ThisVariableIsATemporaryCounter. A C programmer would call that
      variable "tmp", which is much easier to write, and not the least more
      difficult to understand.

      HOWEVER, while mixed-case names are frowned upon, descriptive names for
      global variables are a must. To call a global function "foo" is a
      shooting offense.

      GLOBAL variables (to be used only if you _really_ need them) need to
      have descriptive names, as do global functions. If you have a function
      that counts the number of active users, you should call that
      "count_active_users()" or similar, you should _not_ call it "cntusr()".

      Encoding the type of a function into the name (so-called Hungarian
      notation) is brain damaged - the compiler knows the types anyway and can
      check those, and it only confuses the programmer. No wonder MicroSoft
      makes buggy programs.

      LOCAL variable names should be short, and to the point. If you have
      some random integer loop counter, it should probably be called "i".
      Calling it "loop_counter" is non-productive, if there is no chance of it
      being mis-understood. Similarly, "tmp" can be just about any type of
      variable that is used to hold a temporary value.

      If you are afraid to mix up your local variable names, you have another
      problem, which is called the function-growth-hormone-imbalance syndrome.
      See next chapter.
    15. Re:You should always... by goretexguy · · Score: 1

      Comments? Who needs comments?


      Why do you think its called code ?

    16. Re:You should always... by fitten · · Score: 1

      I think it'll run faster if you remove all the unnecessary white space in the source as well...

    17. Re:You should always... by Anonymous Coward · · Score: 1, Funny
      That's extreme, and at the other end of the spectrum we have PEAR.
      /*
      * (bool) isValidNum(int)
      * Returns true if the passed variable is valid 2 digit integer
      *
      * @author: ten yo
      * @param int $form_numeric_input
      * @access public
      * @return bool
      * @package PEAR wankfast
      * @class random_pear_wankfest
      */
      function isValidNum($form_numeric_input)
      {
      /* note: it's unusual for a PEAR function to be this compact
      I'm sure someone can needlessly pad it out to 50 lines */
      return (ctype_digit($form_numeric_input)<100) ? true : false;
      }
    18. Re:You should always... by AssFace · · Score: 1

      At one of my previous jobs we had code reviews. The leader of one of my projects actually wrote as the main negative point of my code "too many comments".

      I wanted to shit on his desk and set his car on fire.

      --

      There are some odd things afoot now, in the Villa Straylight.
    19. Re:You should always... by Anonymous Coward · · Score: 0

      No but my brain parses it faster. When it gets to be someone elses turn to maintain my code they can upgrade their brain if they have difficulty with my coding style.

    20. Re:You should always... by Anonymous Coward · · Score: 0

      I always name my counters ii, jj, kk, etc. This way if for any reason you need to find/replace all the instances of the counter, you can search for ii. searching for i will get you every 'i' in the code/comments etc.

      QUOTE:

      LOCAL variable names should be short, and to the point. If you have
      some random integer loop counter, it should probably be called "i".

    21. Re:You should always... by Jorkapp · · Score: 1

      Simple, because noone can read it.

      --
      Frink: Nice try floyd, but you were designed for scrubbing, and scrubbing is what you shall do.
    22. Re:You should always... by stinkyfingers · · Score: 1

      Obfuscate. For the sole purpose of testing programmers who don't even know you exist, yet. Make a game of it.

      1) All loops can be be rewritten as
      do-while

      loops. 2) Use the tertiary operator as much as possible. 3) Single statement

      brackets are optional. 4) Remember, the compiler doesn't
      care
      where
      you
      put
      the
      carriage

      returns.

    23. Re:You should always... by thaneross · · Score: 1

      You're just lucky Kent Beck isn't here...

      While I agree comments are important, I think Martin Fowler said it best:

      Any fool can write code that a computer can understand. Good programmers write code that humans can understand.
    24. Re:You should always... by Karma+Sucks · · Score: 1

      Frankly, he was probably right.

      You sure don't take well to criticism, do you?

      --
      (Please browse at -1 to read this comment.)
    25. Re:You should always... by mattstorer · · Score: 1

      Every programmer worth his/her salt knows that source code is self documenting

      ... actually, there's a degree of truth to this. I've had to work on code that's passed through many hands before, and there's nothing worse than having comments that are written poorly, are ambiguous, or don't get updated along with the code they relate to.

      While having comments can be a great thing, they can also be a terrible thing if they misinform. Comments are, IMHO, best when you have a short blurb at the top of a larger block of code, where the higher-level purpose of the code block won't change, even if its implementation does.

      On modern systems, worrying about microseconds is a waste of time unless you're dealing with systems that really need that kind of precision. Most user apps don't, period. Having clean, understandable code is far more important, again IMHO, than saving a few cycles through a cryptic coding style.

      -Matt

    26. Re:You should always... by Anonymous Coward · · Score: 0

      I don't think you would have to comment as to why you were doing it either.

    27. Re:You should always... by pyrrho · · Score: 1

      funny...

      and I know languages where they are not optimized away!

      --

      -pyrrho

    28. Re:You should always... by lgw · · Score: 1

      This is still true of any interpreted language. The payoff is just smaller.

      --
      Socialism: a lie told by totalitarians and believed by fools.
    29. Re:You should always... by david+duncan+scott · · Score: 1

      Not really. Most interpreted languages are pre-tokenized.

      --

      This next song is very sad. Please clap along. -- Robin Zander

    30. Re:You should always... by rjstanford · · Score: 5, Informative

      LOCAL variable names should be short, and to the point. If you have
      some random integer loop counter, it should probably be called "i".
      Calling it "loop_counter" is non-productive, if there is no chance of it
      being mis-understood.


      That last clause is an important one that often gets neglected. In fact, you should never, ever, call a variable loop_counter. That's as bad as pure reverse hungarian - it tells you how its used, not what it means.

      I suggest that, for all non-trivial cases (and I'd prefer to see people err verbosely than compactly), you should use descriptive names. Not loop_counter, but maybe something like curRow? It doesn't have to be long, but at least then as the loop grows over time someone can understand a piece of code more easily than having to scroll back up to check that you are indeed in the "i" loop. Its even more critical when someone comes along and adds a nested (or containing) loop. Or whatever.

      Same with "tmp". If its truly temporary, such as:

      int tmp = getFooCount();
      doSomething(tmp);

      then it should be removed and rewritten as:

      doSomething(getFooCount());

      If its not that temporary, give it a real name. If you insist that it is temporary then you may have a scoping issue - having variables useful but only in part of your function could indicate that your function is doing too much work. If you insist its truly temporary, scope it down: ...
      someRandomCode();
      {
      int foo = getFoo();
      doSomething(foo);
      doSomethingElse(foo);
      }
      moreCode(); ...

      At least now you've guaranteed that it is temporary. Better yet, just name it usefully.

      --
      You're special forces then? That's great! I just love your olympics!
    31. Re:You should always... by Anonymous Coward · · Score: 0

      "The compiler knows the types..."

      Does it? Really?

      "Hungarian notation confuses the programmer."
      No it doesn't. As with all things, you have to get to grips with it, but once you do, there's no problem with finding out the type of a variable by its name.
      Not everything is in Hungarian notation either, short names such as i,j, k are still used too!

    32. Re:You should always... by david+duncan+scott · · Score: 1

      Applesoft wasn't the only strange BASIC. Commodore BASIC encouraged squeezing out the white space to save memory. There was a reason 640K seemed like a lot of memory to Bill Gates -- that was ten Commodores stacked up in a pile.

      --

      This next song is very sad. Please clap along. -- Robin Zander

    33. Re:You should always... by leerpm · · Score: 1

      Every programmer worth his/her salt should write source code that is self documenting... Not many do..

    34. Re:You should always... by pyrrho · · Score: 1

      "I wanted to shit on his desk and set his car on fire."

      that was a sample of one of the comments in your code, isn't it?

      --

      -pyrrho

    35. Re:You should always... by 0D0A · · Score: 1

      The difference between self documenting code and documentation, is that documentation will show the intent of the coder where as the code will only show what the coder chose to write down. This is the essence of "Do what I want you to, not what I tell you to!".

    36. Re:You should always... by Trillan · · Score: 4, Insightful

      With the greatest respect to Linus, but writing a kernel does not make you the authority on programming. It does make you the authority on what particular style you allow in your CVS tree, but that's it.

      I certainly agree that loop_counter is a bad name, though. But rather than use i, I prefer to at least make a note of what sort of objects I'm looping through.

      For instance:

      int taskI;
      int taskCount = GetTaskCount();
      for (taskI=0; taskI<taskCount; taskI++)
      {
      ...
      }

      Code can never be 100% self documenting, but that's no reason not to settle for 0%. Whether you use CamelCase or words_broken_with_underscores is a matter of style, and you should stick with the style of the code base you're working on.

      Anyone who can't or won't work with multiple languages or adopt the necessary style for an existing project is a poor programmer. When you create project, you create the rules. When you work on someone else's project, you follow the rules.

    37. Re:You should always... by geekoid · · Score: 1

      yeah, I think you need to take a breather.

      Clearly the poster was thinking of things like:
      ptrVar

      where as Linus is talking about things like:
      ThisIsAPointerToMyAccountClassGetSavingsMet hod

      --
      The Kruger Dunning explains most post on /. http://en.wikipedia.org/wiki/Dunning%E2%80%93Kruger_effect
    38. Re:You should always... by Anonymous Coward · · Score: 0
      "A good programmer who codes in C should be able to understand what is going on."

      OK, so predict the output of this simple program before running it. (Warning: from the UNIX-hater's Handbook).
      #include <stdio.h>
      main()
      {
      printf("%d\n", foo() + (foo()<<1) + (foo()<<2) + (foo()<<3));
      }

      foo()
      {
      return(fork() ? 1 : 0);
      }
    39. Re:You should always... by myukew · · Score: 1

      you know, gw-basic did this. If you commented on the same line as say the NEXT in a FOR...NEXT was it ran a few millisecends slower.
      Per loop.

    40. Re:You should always... by lgw · · Score: 1

      Most old basics were too (the tokenized version was in memory). Still, if the user runs the script from a text file, it's not "pre-tokenized" yet. The parser has to do its thing before the program can run. Heck, the file that has to be read in is longer if comments are present, and depending on the ratio of I/O speed to what the program does, it can be significant.

      Still, these days an interpreted program would have to be pretty large for the difference to be human-noticible.

      --
      Socialism: a lie told by totalitarians and believed by fools.
    41. Re:You should always... by Anonymous Coward · · Score: 1, Funny
      Sample comments:
      /* Now my boss wants me to update the file control routine.
      * I just updated this section last March. F***ing customers found a failing case. I hate them.
      * I'll have to cancel the beach trip this weekend, to get this done.
      * Then Fred in QA found too many Warnings. I told him to just ignore them, but no!!!!!!
      */
    42. Re:You should always... by Anonymous Coward · · Score: 0

      "A C programmer would call that variable "tmp", which is much easier to write, and not the least more difficult to understand."

      Pfft, n00b. I use "_" for all my temporaries. Now if only I could avoid having to press that pesky shift key.

    43. Re:You should always... by ScytheBlade1 · · Score: 1

      I really don't know what to say.... other than "wtf"... and that's kinda redundant ;)

    44. Re:You should always... by ZeroExistenZ · · Score: 1

      Don't forget stripping all tabs, linefeeds and spaces where possible.

      --
      I think we can keep recursing like this until someone returns 1
    45. Re:You should always... by TheRagingTowel · · Score: 1

      I once heard somewhere that good code doesn't need comments.

      Made me wonder.

      --
      4Z5TX
    46. Re:You should always... by owlstead · · Score: 1

      They could use his humor as a fingerprint. Cntusr? function-growth-hormone-imbalance? It's even better then the X.509 style guide or the original book on C by Kernigan and Richie (who's names I've probably misspelled, my appologies). If you're looking them up, don't forget the editorial on time in the Dr Dobbs.

      And I thank him for kicking the notorious Hungarian notation as well. Nowadays the type will not only be known by the compiler, but by the IDE as well. Please leave out any of such information, it is simply of no use at all.

    47. Re:You should always... by Anonymous Coward · · Score: 0

      I reuse _, _1 etc for temporaries and document that at the head of the project. I've had more complaints since I added boilerplates explaining it than before. Fuck 'em I say, this isn't school anymore!

    48. Re:You should always... by Anonymous Coward · · Score: 0

      Lovely - a slashbot telling Torvalds that he's not *the* authority and then giving advice like he was some sort of authority.

      taskI??? Never seen such an ugly piece of "code"...

    49. Re:You should always... by mattyrobinson69 · · Score: 1

      variable and function names should come from /dev/urandom - thats what real men do

    50. Re:You should always... by Anonymous Coward · · Score: 0

      He's using camelCase variable names and PascalCase function names... WTF? I think this is the part where we all flame him.

    51. Re:You should always... by Trillan · · Score: 1

      I was sharing what I did, not saying I am an authority. My point is just what you are trolling -- there is no absolute authority on matters of coding style.

      Although I do maintain that you should follow the coding standard of whatever project you are working on, and this statement is echoed on the GNU web page somewhere (along with their recommendation to use their style on new projects). (No, I'm not going to look up where again.)

    52. Re:You should always... by ArbitraryConstant · · Score: 1
      I often use "ret" to instead of "tmp" as a place to explicitly put return values so I can get a closer look at them.
      ret = open(path, O_RDONLY, MODE_DONTCARE);
      if (ret < 0) {
      return FILE_ERROR;
      }
      fd = ret;
      Because robust verification of return values can take more than one "if", and I don't want to stomp old values until I'm sure the new one will work. Even if it's not needed in this case, it's a good habbit to get into.
      --
      I rarely criticize things I don't care about.
    53. Re:You should always... by Kehvarl · · Score: 1

      I thought I was the only person who did this, and I always wondered why I did it. -I- have always felt it was explicitly clear what that variable did, but the people I've allowed (tormented with the threat of allowing, actually) to read my code seem to never know why I created it until I actually return it.

    54. Re:You should always... by infogrind · · Score: 1

      If you follow the principle of always keeping your functions short (cf. Refactoring , Fowler, et al., 1999) then short variable names such as i and n are no problem, your code remains clear.

      If your function is so long that you have to use long variable names, something is wrong with your coding style.

    55. Re:You should always... by eric76 · · Score: 1

      You could just skip the source code and patch the executables directly.

    56. Re:You should always... by ArbitraryConstant · · Score: 1

      huh, that's odd.

      When people make notice of it when I do it, it's always something along the lines of "Huh, I like that.".

      --
      I rarely criticize things I don't care about.
    57. Re:You should always... by eric76 · · Score: 1

      I worked at one company years ago where we had a religious war about how many spaces to use for a tab.

    58. Re:You should always... by Anonymous Coward · · Score: 0

      For all you young ones out there, it is Brian W. Kernighan and Dennis M. Ritchie. Those are 2 names you really should know.

    59. Re:You should always... by eric76 · · Score: 1

      To some of us who came from all caps days (you couldn't even print lowercase on the printers), the lure of being able to use mixed case is just too tantalizing to ignore.

    60. Re:You should always... by Anonymous Coward · · Score: 0
      As well you should! Note that this is point #1 in the Linux style guide:
      Chapter 1: Indentation

      Tabs are 8 characters, and thus indentations are also 8 characters.
      There are heretic movements that try to make indentations 4 (or even 2!)
      characters deep, and that is akin to trying to define the value of PI to
      be 3.

      Rationale: The whole idea behind indentation is to clearly define where
      a block of control starts and ends. Especially when you've been looking
      at your screen for 20 straight hours, you'll find it a lot easier to see
      how the indentation works if you have large indentations.

      Now, some people will claim that having 8-character indentations makes
      the code move too far to the right, and makes it hard to read on a
      80-character terminal screen. The answer to that is that if you need
      more than 3 levels of indentation, you're screwed anyway, and should fix
      your program.

      In short, 8-char indents make things easier to read, and have the added
      benefit of warning you when you're nesting your functions too deep.
      Heed that warning.

      Don't put multiple statements on a single line unless you have
      something to hide:

      if (condition) do_this;
      do_something_everytime;

      Outside of comments, documentation and except in Kconfig, spaces are never
      used for indentation, and the above example is deliberately broken.

      Get a decent editor and don't leave whitespace at the end of lines.
    61. Re:You should always... by Thunderbear · · Score: 1

      Applesoft Basic was tokenized for the keywords, but not for linenumbers in programs. This meant that renumbering your program with an increment of one could result in it getting smaller as "9" is only one byte as opposed to "40000".

      --

      --
      Thorbjørn Ravn Andersen "...and...Tubular Bells!"
    62. Re:You should always... by 3.1415926535 · · Score: 1

      In vim, you can search for \<i\>. Other editors probably have something similar.

    63. Re:You should always... by Dun+Malg · · Score: 1
      if(_true==false) _false=true;
      else _false=!true;
      if(!true==_false) _true==true;
      else _true=!_true;

      If it was difficult to write, it should be difficult to read!

      --
      If a job's not worth doing, it's not worth doing right.
    64. Re:You should always... by Pacifix · · Score: 1

      I use variable names. int v1, string v2, float v3, etc. Seems pretty clear to me!

    65. Re:You should always... by Anonymous Coward · · Score: 0

      U.S. Encouraged by Vietnam Vote - Officials Cite 83% Turnout Despite Vietcong Terror - New York Times 9/3/1967

      Yeah, it's funny how oppressed people will turn out in droves for the opportunity to vote, but Democrats always threaten to move to Canada when people don't vote they way they want.

    66. Re:You should always... by eric76 · · Score: 1

      I wish I'd have had a copy of that at the time.

      The result of the war was that I used 8 characters and everyone else used 3 characters.

    67. Re:You should always... by anonymous_wombat · · Score: 1

      About 15 years ago, I heard a story of a programmer who would not multiply or divide by a multiple of 2, but would always shift instead. No one else could maintain his code, but everyone wanted him on their projects. Thank God those people are finally dying off.

    68. Re:You should always... by foobybletch · · Score: 1
      LOCAL variable names should be short, and to the point. If you have some random integer loop counter, it should probably be called "i". Calling it "loop_counter" is non-productive, if there is no chance of it being mis-understood. Similarly, "tmp" can be just about any type of variable that is used to hold a temporary value.

      I'm sorry, but I have to say bollocks to the last clause there. Calling a loop counter "i" means then that it is next to impossible to find out where it is being used.

      Instead of using "i", I would use "index", for a generic case, as usually we're talking about indexing into some array or other data structure. The use of single letter variables names gets even worse when you have nested loops, I've lost count of the number cases where somebody using "i" and "j" as their loop variables have accidentally transposed the references, espcially when we're talking about code that gets changed over time. (i.e. real code, not an example :-)

      It's far better to spend a extra few seconds in giving a meaningful name to a variable, rather than spending hours, debugging some strange intermittent memory overwrite! Let alone the cumulative numbers of hours spend trying to undestand a piece of code when frobnicating it a year later.

      --
      Line eater? What lin
    69. Re:You should always... by Anonymous Coward · · Score: 0

      That's right out of the official C# style guide.

    70. Re:You should always... by Bake · · Score: 1

      why not just use \t?

      That way you could all be happy by having your editors set the preferred number of spaces in a tab.

    71. Re:You should always... by Prof.Phreak · · Score: 1

      ``It was hard to write... it should be hard to read!'' --forgotwho

      --

      "If anything can go wrong, it will." - Murphy

    72. Re: You should always... by gidds · · Score: 1
      Mmm. In fact, to distil this down to a simple rule of thumb:
      The length of an identifier should be inversely proportional to its scope.

      --

      Ceterum censeo subscriptionem esse delendam.

    73. Re:You should always... by Anonymous Coward · · Score: 0

      On 16mhz, 5 meg systems optimiztion made sense. How desparate is the need to 2.3ghz running 1000 meg ram?

      Of course I haven't had the need to write any atmospheric forecasting programs lately.

    74. Re:You should always... by Ignominious+Cow+Herd · · Score: 1

      Sure. You can guarantee its behavior and that it has exactly one bug.

      --
      Lump lingered last in line for brains, and the ones she got were sorta rotten and insane.
    75. Re:You should always... by Anonymous Coward · · Score: 0

      Yeah, it's funny how oppressed people will turn out in droves for the opportunity to vote, but Democrats always threaten to move to Canada when people don't vote they way they want.

      And we in Canada will welcome them up here. As for the other half of you, please stay right where you are.

    76. Re:You should always... by mattgreen · · Score: 1

      Do you consider the Linux kernel the paragon of readability?

      C's built-in types are a trainwreck. If you want to open a file, you can use a FILE structure, but then if you want to work with dates, typically there is a time_t involved there. Oh, and if you want to declare a character, use a char. If you want a wider one, use wchar_t. This makes sense how? There is no consistency here! Functions suck in the same way, but less so (strcpy vs. atoi - both deal with null strings, but they certainly don't start out the same way!) C's insistence on tight function names does not aid memory, either.

      Naming conventions matter a whole lot when it comes to readability. It is 2005. Making your function names longer than 5 characters is not the end of the world!

      Unfortunately, C++ saw fit to continue this idiotic trend. If you want to use a stringstream, you include a header called 'sstream' but then use std::stringstream. But if you want to open a file stream, you include 'fstream' and use std::fstream. A resizable array is not called an array, but rather a vector. A map does not contain keys and values, but rather a pair.

      By now I'm sure I've blasphemed against the holy C family of languages enough. All I'm asking for is clear, expressive, predictable naming conventions.

    77. Re:You should always... by Trillan · · Score: 1

      If it makes you feel like a better person, go right ahead!

      If I was rewriting this code from scratch, I'd reconsider the variable names. I might end up with underscores_like_this for variables. So the variables in the example I gave would be task_count and task_i.

      But I definitely wouldn't use the same convention for variable names vs. other identifiers.

    78. Re:You should always... by Anonymous Coward · · Score: 0

      Well, because there are those of us who religiously believe that in text files tab stops are every 8 characters, dammit. That is the default and there is no standard way to encode it in a file, so if you change it, you consequently either confuse all unix text processing utilities, or you must remember to give every fucking utility a command line argument to specify tab width. This is why anyone tinkering with tab width settings in plain text files is heretic and will be burned on the stake. If you want different indentation, use your editor's automatic indentation facilities.

      Of course, it is possible that my religion is not represented in the grandparent poster's company, so your suggestion might work for them...

    79. Re:You should always... by superswede · · Score: 1

      With years of programming experience, I was please to be told one day to use ii, jj, kk, ll for my iteration variables. Why? Try to search for 'i', 'j' in your code...

    80. Re:You should always... by aixguru1 · · Score: 1

      fork either returns 0 or -1, so a comparison to value 1, then returning 0 should not happen. I believe it would end up returning a NULL value since the if fails... interestingly enough, you would fork four child processes, which would fork 4 child processes, etc, etc... nasty little way to eat or process space. Sort of like the shell script of script a calls script b which calls a.... etc Even worse when you background those and put a wait in there, blamo.

      --
      root 10956 5164 0 Oct 22 - 0:23 sendmail: rejecting connections: load average: 70 (isn't sendmail just too kind)
    81. Re:You should always... by Anonymous Coward · · Score: 0
      Do you consider the Linux kernel the paragon of readability?

      Actually, yes. Try browsing the source online and you'll see that the "make functions that do one thing only and do it well" and "keep functions small and break them up if they get large" rules make even the most complex concepts (for example the NUMA stuff) quite understandable.

      I have never seen as complex a system - in any language - as easy to understand.

    82. Re:You should always... by Anonymous Coward · · Score: 0
      Why's this a problem? Is your editor broken?

      Surely you shouldn't change the language because some people use tools with missing features?

      Next you'll be telling me you shouldn't use "a" or "I" in english because they're hard to search for.

    83. Re:You should always... by Anonymous Coward · · Score: 0
      I wish I hadn't posted here so I could mod you up.

      This was the clearest summary of the issue in this entire long thread.

      Your statement (in it's entirety with the link for those who need more) is now *THE* coding standard for our company. Follow this rule, and all the rest of the silly rules (hungarian, indentation, etc) all become unimportant.

    84. Re:You should always... by Anonymous Coward · · Score: 0

      > With years of programming experience, I was please to be told one day to use
      > ii, jj, kk, ll for my iteration variables. Why? Try to search for 'i', 'j' in your code...

      With years of programming experience, I've *never* had to search for an iteration variable. But if I did, I'd search for the "i++" or "j--" form instead of just "i" or "j."

    85. Re:You should always... by Anonymous Coward · · Score: 0

      Oh dern, and I really wanted to leave this country half-full of nutbags to go to one completely full of 'em.

    86. Re:You should always... by Anonymous Coward · · Score: 0

      Most people critical of Hungarian notation are so only because it's from M$, and they, equally irrationally, hate M$.

    87. Re:You should always... by Anonymous Coward · · Score: 0
      Encoding the type of a function into the name (so-called Hungarian notation) is brain damaged - the compiler knows the types anyway and can check those, and it only confuses the programmer. No wonder MicroSoft makes buggy programs.

      What an asslick. Who uses Hungarian notation on function names? It can be terribly useful for variables, for example:

      std::string strName("LameLinus");
      char* pszName = strName.c_str();
      char szName[10]; strcpy(szName, pszName);

      Hmm, I guess I can make moronic statements and become a god here amongst Slashdotters as well, how about:

      Linus speaks about things he knows nothing about. He probably codes similarly.

    88. Re:You should always... by Anonymous Coward · · Score: 0
      Especially when you've been looking at your screen for 20 straight hours, you'll find it a lot easier to see how the indentation works if you have large indentations.

      Where I work they don't make us look at our screens for 20 straight hours, so we use a more sensible, shorter length of tab.

      What a patently stupid statement, and evidently typical of Linus and his meaningless coding "standards". And to be sensitive to those who look at code for 40 straight hours, shouldn't tabs be 16 chars long? This is not an argument for stupidly-long tab lengths, it's for VIC-20 displays!

    89. Re:You should always... by Anonymous Coward · · Score: 0

      "Run time" ???
      how come?

    90. Re:You should always... by Anonymous Coward · · Score: 0

      > Where I work they don't make us look at our screens for 20 straight hours, so we use a more sensible, shorter length of tab.

      When you're coding on your own, for the love of it, nobody is "making" you look at screens for any length of time. Besides, Linus is (half) joking here.

      And I notice you didn't offer any counterargument as to why a shorter tab length is "more sensible."

    91. Re:You should always... by Anonymous Coward · · Score: 0

      > Most people critical of Hungarian notation are so only because it's from M$, and they, equally irrationally, hate M$.

      On the contrary, there are plenty of rational reasons to hate both Hungarian notation and Microsoft. But, as you point out, it is a Microsoft (specifically Simonyi) creation, which puts it on the list of reasons to hate MS.

    92. Re:You should always... by Anonymous Coward · · Score: 0

      and you call yourself a guru? heh.

    93. Re:You should always... by Anonymous Coward · · Score: 0
      It's horribly non-object-oriented to write Hungarian Notation.

      Note that if you wanted to change your "strName" to objet to some other class - perhaps one that multiply inherits the one you were using and something else with added functionality - the last thing you want to do is rename the variables everywhere.

      It's even more important in C++ when you might start out using a builtin (like int) and might evolve your code to using a class (like the BOOST library's typesafe values with units).

      All your code should know are that "+" and "*" are legal parts of the interface. It shouldn't care whether the value on each side is an int or a class.

      At best, if you use Hungarian Notation name the variable after the *INTERFACE* being used, not the class itself.

    94. Re:You should always... by raznorw · · Score: 1

      While scoping down is a convenient alternative (especially in some older C++ compilers with broken scoping rules, not that most people still use those), tmp variables do have valid uses, such as swapping.

      tmp = a;
      a = b;
      b = tmp;

      Yes...it really is a temporary variable, but it is not simple to remove as in your "doSomething(getFooCount()) example.

      Also, in one particular project I worked on,

      int tmp = getFooCount();
      doSomething(tmp);

      was preferred, not for stylistic or compiler issues, but for debugging. With the debuggers we had to use (code is ported to multiple architectures, some quite old), the extra intermediate value being accessible in a variable made working with the debugger much easier.

    95. Re:You should always... by Lars+T. · · Score: 1

      You mean the people in South Vietnam were oppressed?

      --

      Lars T.

      To the guy who modded me down from perfect to terrible Karma - Apple haters still suck

    96. Re:You should always... by Anonymous Coward · · Score: 0

      doSomething(getFooCount());

      You just called getFooCount() without checking
      its return value.

      Now fall on you knife.

    97. Re:You should always... by rjstanford · · Score: 1

      tmp = a;
      a = b;
      b = tmp;


      Why not simply make an inlined function and call:

      swap(*a, *b);

      int tmp = getFooCount();
      doSomething(tmp);

      was preferred, not for stylistic or compiler issues, but for debugging


      That makes a lot of sense to me... but then you're dealing with a debug variable named "foo". Why not:

      int fooCount = getFooCount();
      doSomething(fooCount);

      ? That way if you have the variable traced, you can see what it is you're looking at.

      --
      You're special forces then? That's great! I just love your olympics!
    98. Re:You should always... by raznorw · · Score: 1

      Well, generic temporary variables are nice when you need to use them often such as,

      CORBA::Boolean result = ...
      if(result) { ... }

      The above construct occured many times throughout the code and while result could have been replaced with
      resultOfCorbaNil (or whatever operation), result was far more concise and descriptive enough to convey meaning. Of course, it might become harder to trace any given "result", but we didn't run into that problem this time.

      With swap as an inlined function, the function block for swap would still (could still) make use of the temporary variable.

  5. Time to post the famous Knuth quote... by xlv · · Score: 4, Informative

    Donald Knuth wrote "We should forget about small efficiencies, about 97% of the time. Premature optimization is the root of all evil."

    1. Re:Time to post the famous Knuth quote... by Anonymous Coward · · Score: 0

      Knuth must be blessed if he's working in an environment where premature optimization is the root of all of his evil.

    2. Re:Time to post the famous Knuth quote... by Anonymous Coward · · Score: 2, Insightful
      I second that.

      Optimisations at such a low level (especially without profiler evidence to prove it) is often a complete waste of time when the remainder of the code is slow due to crappy algorithm or structure choices.

      ...I remember a guy I worked with wrote a "faster" atol type function. His had less code and did much less. I suggested we profile it to demonstrate is coding prowess. Of course his executed slower than the shipped crt version...his suggestion of taking the crt verson and "hacking out the junk" amused the rest of us for a while hehe (Lee, you know who you are)

    3. Re:Time to post the famous Knuth quote... by Rahga · · Score: 1

      "It is practically impossible to teach good programming style to students that [sic] have had prior expose to BASIC; as potential programmers they are mentally mutilated beyond hope of regeneration.
      --E. W. Dijkstra"

      So... Can anybody prove that the root of BASIC is premature optimization?

    4. Re:Time to post the famous Knuth quote... by Anonymous Coward · · Score: 0

      Premature optimization is the root of all evil

      And all this time my g/f was telling me it was premature ejaculation.

    5. Re:Time to post the famous Knuth quote... by Anonymous Coward · · Score: 1, Funny

      We should forget about small efficiencies, about 97% of the time.

      Actually, you can get it up to 98% of the time if you are careful.

    6. Re:Time to post the famous Knuth quote... by WindBourne · · Score: 1

      And by now, isn't that ex-g/f?

      --
      I prefer the "u" in honour as it seems to be missing these days.
    7. Re:Time to post the famous Knuth quote... by Rinisari · · Score: 0, Offtopic

      Actually, women are the root of all evil.

      We know that women like two things, your time and your money,
      therefore...
      women = time * money

      Now time equals money, so
      women = money * money

      Money is the root of all evil, so
      money = sqrt(evil)

      By squaring both sides of the equation,
      money ^ 2 = evil

      Now go back to the equation
      women = money * money

      See where I'm headed?
      women = money ^ 2 = evil

      I hope my female friend doesn't look over here...STOP LOOKING AT THIS! THIS ISN'T MEANT FOR YOU! OW!

    8. Re:Time to post the famous Knuth quote... by Anonymous Coward · · Score: 0

      But if you leave optimizing until the last minute you may discover that the program cannot be made to run fast enough without major architectural changes that require rewriting half of the code.

      Or your sales team may be left grinning stupidly during demos, wondering whether the software has crashed or is just taking its sweet time.

    9. Re:Time to post the famous Knuth quote... by Anonymous Coward · · Score: 0

      Knuth was quoting C.A.R. Hoare and in "The Errors of TeX" he at least gives proper attribution.

    10. Re:Time to post the famous Knuth quote... by too_poland · · Score: 1

      Try to check the difference between while(i>0) { put here your favourite calculation repeated 1M times } and while(i>1) { the same alg, with intermediate values greater than cpu assembly provides (eg. > 255 on ARM7TDMI), with x=y*12 instead of x=y3 + y2 } etc

    11. Re:Time to post the famous Knuth quote... by md65536 · · Score: 1

      That being said, one should not take this as a Commandment and associate fast code with "evil", refusing to even consider speed in design. You can write fast code in general without optimizing it, and without sacrificing readablility. I'm talking general best-practices for fast code, I'm not talking about using tricks and shortcuts.
      If this is not done, if say you have a team of programmers who think fast code is evil, you may find yourself with a ton of slow code. Maybe only 2% of the code contributes to 70% of the runtime (I dunno actual stats), but you may have 50 poorly designed bits of slow code contributing to that 2%, and then when you optimize all of those, the other 98% of the code that used to take 30% time may now take 80% time, all of it slow code.

      Also: small, tight, clean code can often be a lot more readable than long, rambly, superfluous code.

      And a digression: if "if (!ptr)" is unreadable or confusing, you may have a problem. To me, changing that to "if (ptr==NULL)" would be like changing "if not valid pointer," in commenting to "if validity of pointer is lacking".

    12. Re:Time to post the famous Knuth quote... by MBraynard · · Score: 1
      Heya -

      You do the referral in my sig and I will do yours - just shoot me an email when you have done it at mattatbraynarddotcom.

      I already got the Ipod and Xbox free. Good luck.

    13. Re:Time to post the famous Knuth quote... by ivec · · Score: 1

      Yes, but the original quote about premature optimzations should properly be attributed to Tony Hoare, who originally stated it.

      See http://en.wikipedia.org/wiki/Premature_optimizatio n

    14. Re:Time to post the famous Knuth quote... by NoOneInParticular · · Score: 1
      I wholeheartedly agree with this. I've worked in teams that took the "premature optimization" to such heart that they refused to consider efficiency *at all* in the program. The result is a slow mess that will need a complete rewrite to make it snappy.

      Next to "premature optimization is the root of all evil", there should be a second mantra that should say something equivalent to "programmers that don't care about efficiency should be taken out and shot in the foot".

    15. Re:Time to post the famous Knuth quote... by Anonymous Coward · · Score: 0

      I've worked in teams that took the "premature optimization" to such heart that they refused to consider efficiency *at all* in the program.

      That's not what the guy said though. Even if you truly believed that premature optimisation was the cause of all suffering in the world, it still wouldn't lead you to believe that you should refuse to consider efficiency at all.

      If somebody reads that quote and thinks that it means efficiency should be ignored, they need to improve their reading comprehension skills dramatically.

    16. Re:Time to post the famous Knuth quote... by NoOneInParticular · · Score: 1

      That's the problem with lots of people in IT: their reading skills suck! I've found indeed that the quote is often used in this flawed way and even had it used against me early in a project where I suggested to use a reasonable algorithm instead of a naive one. Alas, it was ignored and of course, the application turned out to be so doggishly slow that it was unusable.

  6. Algorithms, Not Stupid Processor Tricks by American+AC+in+Paris · · Score: 5, Insightful
    This is marginally away from the submitter's question, but it warrnats attention:

    The sad truth is that, as far as optimization goes, this isn't where attention is most needed.

    Before we start worrying about things like saving two cycles here and there, we need to start teaching people how to select the proper algorithm for the task at hand.

    There are too many programmers who spend hours turning their code into unreadable mush for the sake of squeezing a few milliseconds out of a loop that runs on the order of O(n!) or O(2^n).

    For 99% of the coders out there, all that needs to be known about code optimization is: pick the right algorithms! Couple this with readable code, and you'll have a program that runs several thousand times faster than it'll ever need to and is easy to maintain--and that's probably all you'll ever need.

    --

    Obliteracy: Words with explosions

    1. Re:Algorithms, Not Stupid Processor Tricks by Anonymous Coward · · Score: 0

      Heh. Wasn't that long ago that every other guy's homegrown 3D engine (software rendering, mind you, this was the 100mhz pentium era) had an ultra-optimized version of bubblesort doing the depth sorting of polygons in a painter's algorithm type affair.

      I certainly hope those people are better educated these days.

    2. Re:Algorithms, Not Stupid Processor Tricks by flynt · · Score: 3, Insightful

      But this would require people to actually get computer science degrees, or have enough self-motivation to read books on algorithms and do the excercises. For most, that's too much to ask, since they cannot see how to apply the theory they learn in school to practice. The ones that can apply the theory are the good programmers. The ones that can't or never learned the theory in the first place probably aren't.

    3. Re:Algorithms, Not Stupid Processor Tricks by Vellmont · · Score: 1

      I couldn't agree more. To expand on this thought, a programmer can't anticipate all the optimizations and tricks that happen at the processor level, therefore the minute little optimizations that a programmer thinks might make the code faster might actually wind up making it slower! Processors and processor optimizations also change with time, so you should rely on your compiler for those sorts of optimizations.

      --
      AccountKiller
    4. Re:Algorithms, Not Stupid Processor Tricks by jdunn14 · · Score: 2, Insightful

      I agree with you to a point. Do not try to squeeze a couple cycles here and there. Pick the right algorithm, but realize that n vs. n^2 vs. 2^n is not a big deal in 99% of applications. Code it so it works first. Make it go. Then, if it sucks performance-wise, replace those slow algorithms. I've seen too many people, myself included, who try to ensure that they've picked the perfect algorithm for the job, but take 4 times longer to design and write the code. Write the damn thing first. Keep it readable and maintainable first.

      The worst people are those college students completing early algorithms classes. They've just been shown the power of the algorithms, and now they feel that everything must use them. Realistically, if you're working with 10 objects, 100 objects, 1000 objects n^2 often isn't a big deal on a 1ghz+ processor. Learn the tools called profilers that enable you to find where the slow points are and optimize after it basically works. Of course, original design does need to be reasonably modular to allow you to replace algorithms as needed.

      Anyway, just my 2 cents after having not finished some projects because I got too caught up in the algorithm and speed details that on reflection were probably not necessary.

    5. Re:Algorithms, Not Stupid Processor Tricks by lgw · · Score: 2, Insightful

      Wasn't that long ago that every other guy's homegrown 3D engine (software rendering, mind you, this was the 100mhz pentium era) had an ultra-optimized version of bubblesort doing the depth sorting of polygons in a painter's algorithm type affair.

      I certainly hope those people are better educated these days.


      It's almost impossible to beat an optimised assembly bubble-sort when sorting small data sets (up to hundreds, sometimes even thousands). It takes a while for better algorithmic performance to overcome a good static effeciency multiplier.

      It's becoming less of an issue as CPU instruction pipelines get larger (and on-chip cache gets faster), but at that time fitting your entire algorithm into the instruction pipeline could mean execution 10 to 30 times as fast.

      --
      Socialism: a lie told by totalitarians and believed by fools.
    6. Re:Algorithms, Not Stupid Processor Tricks by Flyboy+Connor · · Score: 4, Interesting
      Quite agree, it's about the algorithm, not about the code.

      One of the finest moments in my programming career was when my boss asked me to see if I could gain a speed improvement in a program that surveyed a huge datastore and generated volumes of text from it. This program had to run once a month, and deliver its result in the same month. The program that was originally written, unfortunately, took three months to run (it started out OK, but the data store had grown considerably). They had asked one of our "best programmers" to create a faster version of the program. He did that by reprogramming the entire thing in assembly (you may now understand why managers thought he was one of the best programmers). It took him six whole months to finish the new version. The resulting program completed the task in just about one month. However, my boss was afraid that when the datastore would grow a bit more, we would again be in trouble. That's when he asked me to look it over. I started by investigating the problem, which at first glance looked like a network traversing problem. I soon realised it could be solved by a nested matrix multiplication (which is, of course, a standard way to discover paths in a network). It was a matrix with about a million rows and columns, but since it contained only zeroes and ones (with a couple of thousands times more zeroes than ones), the multiplication was easy to implement in a fast way. Within half-a-day, I had built a prototype program in a high-level language which did the whole job in a few hours.

      While I am still pleased with this result, I really think it came off so well not because I was so smart, but because the assembly programmer was not really worthy of the name. Still, I often use this as an illustration for students who are writing illegible code and argue that it is so very fast.

    7. Re:Algorithms, Not Stupid Processor Tricks by Kenard · · Score: 1

      So, you think people without computer science degrees are incapable of choosing the right algorithm, so they should optimize their code instead?

      --
      (appended to the end of comments you post)
    8. Re:Algorithms, Not Stupid Processor Tricks by Anonymous Coward · · Score: 0

      No, but people with computer science degrees are more likely to choose the right algorithm [etc.]

    9. Re:Algorithms, Not Stupid Processor Tricks by Karma+Farmer · · Score: 1

      except that painters algo is a perfect place to use a heap sort.

    10. Re:Algorithms, Not Stupid Processor Tricks by American+AC+in+Paris · · Score: 1
      A fair point--and a trap I've had to haul myself out of on a number of occasions, too...

      Perhaps a better way to put it is that people should be able to recognize bad algorithm choices and go with something which, while perhaps not optimal, will work quickly for the application at hand.

      --

      Obliteracy: Words with explosions

    11. Re:Algorithms, Not Stupid Processor Tricks by Anonymous Coward · · Score: 0

      My job is to go in and make things work faster when they don't perform well. I've yet to find a case where instruction-level optimization cured anything. If you're that close to the wire, wait 3 months and a newer, faster processor will solve the problem for you.

      OTOH, I've solved more than one problem by simply switching to a more appropriate algorithm. That often speeds things up by 2-3 orders of magnitude, whereas instruction tweaking is inherently an additive, not a multiplicative form of optimization.

      Some of the compilers I've worked with produce code I'd be afraid to go in and hand-tweak. They optimized instruction processing to the point where anyone attempting to muck with the code by hand would probably miss something done 25 instructions back and cause the whole thing to crash. AND they RE-optimize to that degree everytime you change the HLL source code.

      Bottom line: If you want to optimize for something, try optimizing for reliability. Far too much software out there is unreliable crap, no matter what language(s) it was written in.

    12. Re:Algorithms, Not Stupid Processor Tricks by glenebob · · Score: 1

      I disagree. In my experience, it's as obvious as the nose on your face what algorithm to use. If it isn't, either you should find another line of work, or the difference is minimal anyway. Use the right algo to begin with, then you won't waste time later adapting your code to a different one.

    13. Re:Algorithms, Not Stupid Processor Tricks by flynt · · Score: 1

      No, I think people who A) don't have CS degress OR as my original post said, B) "have enough self-motivation to read books on algorithms and do the excercises." probably cannot 1)choose the correct algorithm for a given task 2)even know or care why they should want to pick a good algorithm and 3)couldn't optimize their code anyway, since that usually involves a deeper understanding of what's really going on than does choosing a good algorithm.

    14. Re:Algorithms, Not Stupid Processor Tricks by raindog_mx · · Score: 1

      I envy you. I'm a programmer and I'd like to learn to take the most advantage out of algorithms but my school isn't any good and I have to learn all the stuff that interests me by myself while doing stupid VisualBasic.net homework excercises. I had a data structures and algorithms course but it sucked.

      I've read here and there about algorithms but with what I've learned I haven't been able to use them. I have to reinvent the wheel cheesely almost everytime I find a situation where I know algorithms should be used.

      Can you give me some pointer to where to start learning by myself? Also I found a couple algorithm dictionaries but they're not very useful to me since I'm not that familiar with the terms.

      Thanks and sorry for the rookie-newbie-whiny-off-topicness.
    15. Re:Algorithms, Not Stupid Processor Tricks by Confuse+Ed · · Score: 1

      re: pick the right algorithms

      To add to that - if you have a good algorithm library available, make sure that you familiarize yourself with its documented performance - and use it : many man years of effort have (hopefully) been put in to ensuring that it works accurately and efficiently

      The best example I can think of that is great for many mundane things is probably the C++ STL's algorithm and container template libraries - you have plenty of choice of containers to choose from, all with documented big O performance, and the fact that they are templates (should) let the compiler do as good a job at compile time optimization as you're ever likely to get

      <rant>one of my pet annoyances at the moment is that with the .NET libraries seem to have taken a step several years backwards on this front (compared to C++ STL or Java's class libraries) - out of the box their 'collections' libraries appear to basically give you a choice of a vector (Array) or a hash table : nothing comparable to the STL's set, deque, linkedlist or map (red-black tree based dictionary) which must form the foundations of many algorithms for simple data processing</rant>

    16. Re:Algorithms, Not Stupid Processor Tricks by dragons_flight · · Score: 2, Interesting

      As someone that probably operates in the world of the other 1% (academic progammer with computational tasks measured in hours, days, or even weeks), I can still say that it is almost always about the algorithm.

      Every once in a while it really is worth careful instruction level optimization when you have a loop that must execute more than 100 million times, or some such. But the biggest gains in computational speed are always about figuring out the best approach to a problem.

    17. Re:Algorithms, Not Stupid Processor Tricks by bgalehouse · · Score: 1
      For many parts of many real world systems, one can get by without awareness of O(n) versus O(n^2), etc.

      But then every once in a while will bite you in ass badly. I once fixed a system that was slow to log in, at least for administrators. They had a multi-tiered security model with each "role" assigning multiple individual permissions. Similarly, a particular permission could and would be granted by multiple roles.

      The problem code turned out to be a "cache" which contained an aray element for each (role, permission) where the role was held by the user logging in. Effectivly, it was an O(n^2) solution to an O(n) or at most O(n log n) problem. It meant that administrator logins took on the order of a minute, and it increased the size of the client memory footprint by about ten of megabytes.

      Thing is, this whole assembly was the result of an "optimization". Somebody had found a need to reduce the number of database accesses. The problem wasn't a question of focus, it was a question of competance and a programmer who failed to acknowledge a certain lack. Letting yourself become sloppy with regards to algorithm selection has it's own dangers.

    18. Re:Algorithms, Not Stupid Processor Tricks by arodland · · Score: 1

      There's a significant difference between n^2 and 2^n for all n greater than 4, so maybe you need a better example. :)

    19. Re:Algorithms, Not Stupid Processor Tricks by lgw · · Score: 2, Insightful
      The places code most needs optimizaion are unlikely to be helped by the compiler anyway:
      • Unnecessary use of malloc/new instead of just using the stack
      • Unnecessary disk I/O
      • Not considering on which side of the network a calculation should be performed
      There are a few places where algorithmic optimization can help, but geenrally only with very new programmers. Far more often, it's the unintended and quite expensive consequences of library calls that cause much performance greif.
      --
      Socialism: a lie told by totalitarians and believed by fools.
    20. Re:Algorithms, Not Stupid Processor Tricks by Osty · · Score: 1

      Can you give me some pointer to where to start learning by myself? Also I found a couple algorithm dictionaries but they're not very useful to me since I'm not that familiar with the terms.

      You only need one book: Introduction to Algorithms, also referred to simply as CLR (for the authors, Cormen, Leiserson, and Rivest, though they've added Stein for the 2nd Edition and it should probably be called CLRS). That's all you really need to get started. You're not going to go through it in an evening, or even a month, so it's money well-spent. I still pull out my 1st edition copy from time to time in my job.

      Eventually you'll want to move on to other books as well, such as Design Patterns by the Gang of Four. CLR will keep you busy for a long time, though.

    21. Re:Algorithms, Not Stupid Processor Tricks by lgw · · Score: 1

      I've never seen a perfect place to use a heap sort - is the data already in a binary tree or something?

      --
      Socialism: a lie told by totalitarians and believed by fools.
    22. Re:Algorithms, Not Stupid Processor Tricks by jdunn14 · · Score: 1

      Fair enough, but my point was more along the lines of initial contruction. I.e. if you're doing optimization then yes, you must be extremely careful with your choice of algorithms specifically because of problems like that. But, I'd argue that in many cases when an application is first being built it's really more important to get an initial product working, then worry more about the algorithms. It may take some additional time in the portions of the code where you do need to optimize, but in many cases you'll find that the initial construction was adaquate.

      I'll also take a minute to address a couple of other responses. 2^n n^2 at 10 is 1024 and 100. You know what? On a modern machine you often find that 100 vs. 1000 operations is still unnoticable. Program start-up time tends to outweight a lot of operations, but then again I'm not writing heavy computation programs. Lastly, to the guy who said that if it's not obvious what algorithm to use then you should be in another line of work. Look, use the obvious easy one, it's just there's always sooo many ways to do something, and there's likely a better one you're not thinking of. Point being, don't worry about that as some of us are want to do, and see if you need to do some harded thinking later.

      It all comes down to the fact that at this point the most expensive thing in a development station these days is between the seat and the keyboard. Man hours are costly, processor time usually isn't.

    23. Re:Algorithms, Not Stupid Processor Tricks by bgalehouse · · Score: 1
      To a large extent, I agree with you. I'd like to point out though that sometimes algorithmic decisions end up ingrained into the rest of the system. Come to think of it, much of the heavy lifting in fixing up the aformentioned login process came from maintaining bug compatibility. There were a number of eccentricities and a very large security model built to work with them. If you've modularized enough to replace algorithms easily you are in very good shape irregardless.

      Regarding the obviousness of algorithms, I'm reminded of another problem from the real world. You've a bunch of montly payroll data 30 years for each person, perhaps. The specification requires that you find for each person the four highest non-overlapping years of salary. I.E. the four non-overlapping 12 month periods which when averaged give the highest number. There is a solution which is O(n log n) in the number of months. I took me a day or two to find it, but maybe it is obvious to some...

    24. Re:Algorithms, Not Stupid Processor Tricks by owlstead · · Score: 1

      Select the proper algorithm? Well, yes, but they need to make a proper design first. And getting some requirements before that is even better. If you don't have a proper design, choosing an algorithm to implement a method you never would use is obviously of no value at all.

    25. Re:Algorithms, Not Stupid Processor Tricks by Anonymous Coward · · Score: 0

      You've hit the nail on the head. People fall into relying on techniques far too readily in their programming life, and using little else to solve any given problem in some ridiculous big-O time. It's shocking how common I see iterating through huge lists or arrays to find their length, or finding an element with minimum or maximum of some property on a frame by frame basis. Sometimes they've been seen to be a bottleneck in the profiler, so they're accompanied by optimisations adhering to the 'make the inner loop fast' principle - even being written in assembly, while not worring that the inner loop runs an exponential number of times more than necessary with a half decent algorithm.

      Containers are a particular sore point, of which most newer languages have a collection. C++ STL containers are horribly ugly and long winded to use for beginners (or life long C adherents), and their design owes almost as much to the genericity and tacked-on nature of the language as the underlying algorithm.

      C# and Java implement containers much better, and hopefully they will go some way to improving the situation. But I doubt it, they are often lost within huge libraries of other classes to shoot yourself in the foot with.

    26. Re:Algorithms, Not Stupid Processor Tricks by beelsebob · · Score: 4, Informative
      That's not really the point being made though - the question really is "is it worth spending the next week trying to make optimisations, or coding a better algorithm to do this."

      And while we're at it - n^2 vs 2^n *is* a big deal when working on 1ghz+ systems... If we have 1000 objects, an operation that takes 10 cycles and an n^2 algorithm, then we get a runtime of 0.01 seconds (10 x 1000 x 1000 cycles ), if we have a 2^n algorithm then we get a runtime in the hours, and no amount of optimizing the code in the loop (even down to one instruction) is going to get us anywhere near the n^2 algorithm.

    27. Re:Algorithms, Not Stupid Processor Tricks by Anonymous Coward · · Score: 1, Informative
      Heap sort can be done in place on an array of random data, since it's easy to interpret an array as a binary tree:
      parent(i) = i/2
      children(i) = i*2, i*2+1
    28. Re:Algorithms, Not Stupid Processor Tricks by Anonymous Coward · · Score: 0

      (The pun on 'genericity' was an accident guv'nor :) )

    29. Re:Algorithms, Not Stupid Processor Tricks by jsebrech · · Score: 1

      For 99% of the coders out there, all that needs to be known about code optimization is: pick the right algorithms!

      Very true. Micro-optimization is only useful if your code spends the majority of its time in a small subroutine or loop. Very few programs nowadays actually still do that. Most programs spend the majority of the time waiting on the user, and when they're not, they perform such diverse tasks that micro-optimization benefits very little.

      What is most important is making a clean functional design first. If your design is sound, you can always optimize it later, if necessary. However, if you start optimizing from the start, not only will you be spending your time optimizing non-critical code paths, but you'll make your code so complicated that the design will suffer and actually preclude doing optimization the right way (based on profiling and seeing where performance must be improved). And that's not even talking about the increased bug incidence rate produced by unnecessarily complicated or unreadable code. In most modern software development projects the prime problem is not performance, it's getting rid of bugs so you can ship your product. Worrying about performance only makes sense if your product is truly too slow, and few products nowadays really are. I realise many purists find this concept offensive, but hardware is much cheaper than developer resources, so it is much more cost-effective to focus your resources on decreasing the bug rate than on increasing performance.

    30. Re:Algorithms, Not Stupid Processor Tricks by doktor-hladnjak · · Score: 2, Insightful

      Heap sort can be worth it if you don't need all of the elements to be sorted. For example, say you wanted only the smallest 1% of elements from an array sorted.

      A heap can be constructed in linear time, but extracting each next smallest element takes log time. Hence, getting the m smallest/largest elements out of an array of n elements takes O(n + m log n). If m is small, we're talking linear sorting time wrt to the total size overall. If n = m, the whole thing becomes O(n log n), which is the provably lowest bound on sorting any ordered sequence. However, in practice the heap overhead usually makes something like quicksort faster in such cases where m is close to n.

      A classical example of where you might use this is Kruskal's minimum spanning tree algorithm. For a large graph, typically only a smallish fraction of the edges is ever needed. With heap sort, you avoid having to fully sort all the edges by weight.

    31. Re:Algorithms, Not Stupid Processor Tricks by IamTheRealMike · · Score: 1
      ... and the ones that are good at theory and not at practice become academics. It cuts both ways: good programmers understand algorithmic optimisation but also very practical details like how compilers optimise code and what branch prediction is.

      Algorithmic optimisation is definitely important but it's not the be-all and end all of optimisation. In particular a lot of real world optimisation tasks aren't related to pure runtime speed. They're things like "how do I make my program use less memory" and "how do I make it start quicker" or even "how do I make it feel fast" which has more to do with psychology than maths. A lot of desktop software especially is not CPU bound most of the time, so a zen-like understanding of sorting algorithms will only get you so far.

    32. Re:Algorithms, Not Stupid Processor Tricks by Anonymous Coward · · Score: 0

      Partially true, as far as it goes, but you MUST profile first.

      You wouldn't believe the number of times that I've shaved 70% of the runtime of a program by profiling already optimized code. Usually it's due to people not really understanding temporaries that the compiler has to generate with poor c++ practices.

      I usually do this right after the supposedly senior developer has sworn up and down that there's nothing that can be done to improve speed.... ;>

    33. Re:Algorithms, Not Stupid Processor Tricks by mp3phish · · Score: 1

      Yes, you make a valid point. However your point is about a scenerio which (relatively) never exists. That is why some of the parents are talking about most of the time it doesn't matter which algorithm you use if you are using sufficiently small data sets (most cases in everyday coding). In fact, when this is the case, it is usually faster (in coding, and in finished binary) to choose the more straightforward algorithm even if it happens to be O(2^n). In many (most?) cases you will find that a low iteration speed in O(2^n) algorithms and a very high iteration time in the other "faster" one.

      Scaleable algorithms don't mean anything unless you plan on scaling your application past the breaking point. And i just think the parents are talking about this scenerio (which is if not most of the time, at least a majority of the time).

      --
      Your ignorance is infinitely greater than you realize.
    34. Re:Algorithms, Not Stupid Processor Tricks by exp(pi*sqrt(163)) · · Score: 1

      Reminds me of a project I was working on years ago. We needed to represent a bunch of data as a directed acyclic graph - typically with a bounded number of edges per object. A good way to represent connectivity in such a graph is by storing pointers in the graph vertoces pointing along the directed edges of the graph. With N objects and E edges you need something like O(N+E) storage to represent such a thing. But my colleague had read that you can use adjacency matrices to represent graphs and decided to use them. This uses O(N^2) storage and means many of the algorithms take O(N^2) time instead of O(N) (or worse, O(N) time instead of O(1)). To me this was an obviously brain dead decision to make. But when I pointed this out the guy starts quoting Knuth on me (or Hoare, or whoever) and how it wasn't time to optimize yet. So the moral is: one man's optimization is another man's choice of algorithm. (Of course I was right in this case...)

      --
      Doesn't it make you feel good to know that our freedoms are protected by politicans, lawyers and journalists.
    35. Re:Algorithms, Not Stupid Processor Tricks by Anonymous Coward · · Score: 0

      Each successive frame in a software 3D engine maintains a high amount of temporal coherence. The polygons stay at approximately the same depth relative to each other most of the time. Even when the entire scene changes, the number of tris was kept very very low in those days, so the performance loss due to sorting was negligible compared to rendering the polys themselves.

      When you take that all into account, bubblesort is one of the best sorting algorithms *for that specific situation*. Big-O notation means nothing if you know your input will be less than so-and-so size and that at that size, the clock cycles saved on bubble-sort vs qsort (or whatever) are worth it.

      Don't be hatin' on the bubble-sort; every algorithm has (perhaps limited) uses.

    36. Re: Algorithms, Not Stupid Processor Tricks by gidds · · Score: 2, Insightful
      The knack is knowing when to go for something flash, and when to use something simple, even if it theoretically performs worse.

      And that knack is called profiling.

      It doesn't need to be anything fancy, or use flash tools -- in fact, when it's most needed, the best method is counting seconds in your head!

      For example, an application I've worked on recently started with a bubble sort, which was taking the best part of a minute to run (handheld machine). We tried a quicksort, but the slowness of recursion in this language made hardly any faster. So I ended up with a combsort, which is a bubble sort variation -- much simpler than the quicksort, and with a higher big-O order, but the much lower overhead made it run in a fraction of the time. It was nowhere near as flash, but it was a better choice for the app.

      The important points here are a) I wouldn't have realised how inappropriate quicksort was if I hadn't compared it, and b) an advanced algorithm can run slower than a simpler one, especially with small numbers or bad language support). Don't rely on preconceptions.

      --

      Ceterum censeo subscriptionem esse delendam.

    37. Re:Algorithms, Not Stupid Processor Tricks by omb · · Score: 1

      Right on, Absolutel correct

    38. Re:Algorithms, Not Stupid Processor Tricks by Anonymous Coward · · Score: 0
      *yawn* What boring advice.

      Every freshman CS student learns to look at O() stuff. But to really optimize, you have to get your feet wet and it takes years of practice.

      Replacing O(n^2) code with O(log(n)) code is something any youngster can do, but to shave 12 clock cycles off, takes an even sharper, younger (yet paradoxically more experienced) mind.

      I trust hackers more than computer scientists. Why? Because a hacker can learn computer science, but can a computer scientist learn to hack? I THINK NOT!

    39. Re: Algorithms, Not Stupid Processor Tricks by JollyFinn · · Score: 1

      The better O(n) algorithm runs much faster on big datasets.
      O(n) vs O(n) big difference if the n==10 000, you can count how much faster

      Easy if you KNOW that number of elements you are going to operate >20 then almost any n^2 algorithm will beat 2^n; Think. Difference between 1 million vs 400 iterations.

      There are way more shorting algorithms than bubble sort or quicksort. I personally dislike both of them, quicksort has buble sort slowness when you sort already sorted arrays, but with all the increased overhead assosiated with it. Basicly quicksort is not theoreticly superiour algorithm it was found out practicly really fast at some point of time. It beats bubble sort when done with really unordered data on large arrays, but there are algorithms that don't have such weaknesses and that can get same average case. Quick sorts WORST case is O(n^2) which is bubbleshorts complexity always.
      Quickshorts best case is O(n) And average case O(n log n) for instance mergesort and heap sort have O(n log n) Always.
      I think it was the quickshorts data dependence that got you not the weakness of recursion. It got the overhead, but without the threoretical advantage it hold. The most important to know is HOW LARGE datasets you are about to sort. How ever the code cache issues might make it simpler to use just one shorting algorithm and that makes it NOT quicksort.
      BTW: C library quickshort is not the most optimized way to do it anyway, it has overhead of additional function call for comparison operation and if you know your data type youd better do your own quicksort. Still I prefer mergesort or heapsort over quicksort, since both of them are more general purpose.

      --
      Emacs is good operating system, but it has one flaw: Its text editor could be better.
    40. Re:Algorithms, Not Stupid Processor Tricks by gowen · · Score: 1
      Pick the right algorithm, but realize that n vs. n^2 vs. 2^n is not a big deal in 99% of applications. Code it so it works first. Make it go. Then, if it sucks performance-wise, replace those slow algorithms.
      And, as a rider to this, modularise. If you've a choice of algorithms and don't know which one to use, decide on an generic interface to your algorithm *first*, then code one of them. If that's sub-optimal, code another using the same interface, with all the internal functions/subroutines as well hidden from the algorithm calling them as your language choice allows.
      --
      Athletic Scholarships to universities make as much sense as academic scholarships to sports teams.
    41. Re: Algorithms, Not Stupid Processor Tricks by gidds · · Score: 1
      Er, yes, of course for large data sizes, the order will predominate. But my point is that what counts as 'large' varies a lot. Some cases will rarely or never reach that size, and the constant overheads will be the dominant factor.

      In the case I mentioned, we were talking in the tens or hundreds, so the overheads dominated. (In OPL, function calls are relatively expensive, so after the testing I did I'm fairly sure it was the recursion which slowed things down.)

      It's true that a naive quicksort (no 'h'!) implementation is worst-case on ordered data, but most people use one of the variations such as picking the pivot from the middle element, or using median-of-three, which make ordered data best-case. (That's what I did.) And if it comes to that, a simple bubble-sort tweak can make it even better (linear) on ordered data!

      As you say, there are many other sorting algorithms, each with their own features and assumptions. Do you need stability (i.e. preserving the order of records with the same key)? If so, quicksort won't do. Is the data too large to fit into random-access memory? Then you need one of the tape-based sorts such as the polyphase mergesort. Do the keys fit into a limited range? If so, a pigeonhole sort can run in linear time! (Another technique I've used to great effect.) Do you need to use no extra memory (not even stack)? Then a non-recursive in-place algorithm such as heapsort or combsort can do the job. Do you know anything about the input? If it's almost ordered to start with, a simple insertion sort can beat most others. And so on, and so on.

      Even the usual big-O algorithm analysis tends to look only at comparisons and exchanges. If one of those is much more expensive than the other, or there are other operations (such as function calls) which are relatively expensive, then you have to form your own judgements, which might be different from the standard wisdom.

      So don't reach for quicksort every time -- know your data, know your conditions, and use something appropriate for both!

      --

      Ceterum censeo subscriptionem esse delendam.

    42. Re: Algorithms, Not Stupid Processor Tricks by beelsebob · · Score: 1

      This though is exactly why when Hoare came up with quicksort he suggested that the algorithm didn't just partition and sort. He suggested that the algorithm, test the size of the data set, if it was smaller than (IIRC) 20 items, then it should insertion sort it, and otherwise it should partition and sort. I agree with your point entirely - and I think you agree with mine... That we should think about the algorithm being chosen carefully, because by picking the *right* one we're likely to get much much more gain than managing to remove one instruction from a loop.

    43. Re:Algorithms, Not Stupid Processor Tricks by darkmeridian · · Score: 1

      The lesson is think before you write. Make sure you are answering the right *problem* before you think about writing down the right *solution*.

      I once had a calculus final with a fourth of the points assigned to calculating the volume of a figure standing along the y-axis. The question would have required multiple integrations. However, I flipped the figure onto its side along the x-axis. The problem devolved into a solid of rotation, which was a single integration.

      --
      A NYC lawyer blogs. http://www.chuangblog.com/
    44. Re:Algorithms, Not Stupid Processor Tricks by dbueno · · Score: 1
      But this would require people to actually get computer science degrees, or have enough self-motivation to read books on algorithms and do the excercises. For most, that's too much to ask

      Why is that a problem? Being a good coder is not something you can pick up a few books on and be good at in a weekend. It's both a skill and a discipline. Part of the discipline (and practice) is actually taking advantange of the large numbers of people (like Dijkstra, Knuth, and countless others) who have faced the exact problem your boss has put before you (at least it's the same problem in some incarnation), formalized it, and come up with a solution. You shouldn't try to reinvent the wheel. With overwhelming probability your solution will suck (i.e. the algorithm will have terrible time complexity) and theirs will be good.

      Would you argue that aerospace engineers shouldn't learn differential equations because "it's too much to ask"? No, it's a necessary part of the discipline to understand advances in the field and to be competent. The same goes for learning algorithms and learning how to characterize their time and space complexity.

    45. Re:Algorithms, Not Stupid Processor Tricks by flynt · · Score: 1

      I agree with you 100%. By "too much to ask" I meant, most people simply aren't WILLING to put in that much work to become good at something, which I'm sure you'll agree to. Everything you say is correct though.

    46. Re:Algorithms, Not Stupid Processor Tricks by Zork+the+Almighty · · Score: 1

      I'm sorry, but if you are using an exponential time algorithm where a polynomial time algorithm will do, then you are probably incompetent. Your point more appropriate for polynomial time algorithms, where extra work can often turn an O(n^3) operation into O(n^2 log(n)) or something.

      An important thing to keep in mind is that you can often get better average case complexity by employing some sort of simple caching mechanism. This is especially true in high-level languages, where you can often do it in two or three lines of code. An O(n^3) algorithm with caching might run in O(n^2) 95% of the time, which would look pretty good next to the O(n^2 log(n)) algorithm.

      --

      In Soviet America the banks rob you!
    47. Re:Algorithms, Not Stupid Processor Tricks by devillion · · Score: 1
      You are probably right but real coders code code which already uses the best possible O(f(n)) algorithm (maybe further improved/developed by himself). For serious computing the best algorithm can still be too slow.

      I have problems/methods which can take hours/days/months to run (even when simplified to get crude answers): machine learning, matrix decomposition, monte carlo methods, fourier&wavelet transforms, principal&independent component analysis, variational bayesian methods, thousands or millions of variables.

    48. Re:Algorithms, Not Stupid Processor Tricks by srmalloy · · Score: 1
      If n = m, the whole thing becomes O(n log n), which is the provably lowest bound on sorting any ordered sequence.

      For sorting on a computer, yes. However, it's easy to construct a gedanken-experiment demonstrating an O(n) sort algorithm. Take a number of thin rods (the demonstration used dry spaghetti) equal to the number of values to be sorted, and cut the rods in lengths proportional to the values. Sweep all the rods together into a single bundle, and whack one end on a tabletop to align that end. As long as there is more than one rod in the bundle, take the rod that's sticking up the furthest and remove it, putting it down sequentially next to all the other removed rods. This works in O(n) time because you can compare all the lengths(values) at once looking at the bundle; that kind of comparison is impossible to do computationally. It's also functionally useless as a real-world tool because, while the sort time is linear, the scaling factor is so incredibly huge that even an O(n^2) sort on a Commodore PET with all the values typed in by hand would be faster -- the algorithm may be more efficient, but it can only be implemented on incredibly slow hardware, making a less efficient algorithm on a faster machine more useful.

  7. Neither are correct. by Stavr0 · · Score: 0
    if (0!=ptr) is the best way.
    • Putting the value on the left side prevents == VS = mixups
    • Relying on NULL #define-ition to be compatible with all pointer types is risky. When the compiler sees 0 and a pointer comparison it'll do the right thing.
    1. Re:Neither are correct. by nurd68 · · Score: 1

      However, this is predicated upon the fact that the system defined NULL is 0 (because typically, if whatever you're trying to do fails, the pointer you supplied would be set to NULL, which does not have to be 0).

    2. Re:Neither are correct. by haagmm · · Score: 1

      #ifndef NULL #define NULL 0 #endif always works fine for me.

    3. Re:Neither are correct. by ikegami · · Score: 1
      Relying on NULL #define-ition to be compatible with all pointer types is risky.

      No more risky than assuming that 0 is compatible with all pointer types.

    4. Re:Neither are correct. by Acy+James+Stapp · · Score: 1

      Typically NULL is defined as ((void *)0). In most cases it doesn't make any difference but when you have two overloaded functions differentiated by only an int/pointer parameter, it's easier to select the correct one using NULL when it is defined as a pointer type.

      That being said, I believe NULL is an abomination and should be introduced into the language as a special token 'null', similar to 'true' and 'false'.

      --
      -- Too lazy to get a lower UID.
    5. Re:Neither are correct. by Grant_Watson · · Score: 1

      In ANSI C, the compiler is guaranteed to figure out what a zero means when used as a pointer, even if the system's value for a null pointer is different.

    6. Re:Neither are correct. by Profane+MuthaFucka · · Score: 1

      What compiler are you using that doesn't issue a warning for the '=' used in an if statement?

      And using NULL is not risky. It's always compatible with pointer types, without exception. Do you have an example of what you are talking about?

      --
      Fascism trolls keeping me up every night. When I starts a preachin', he HITS ME WITH HIS REICH!
    7. Re:Neither are correct. by HeghmoH · · Score: 2, Insightful

      Putting the value on the left side prevents == VS = mixups

      So does using -W -Wall -Werror, and that lets you write your statements naturally and protects you when comparing two variables.

      Relying on NULL #define-ition to be compatible with all pointer types is risky.

      Relying on behavior that is explicitly specified in the ISO/ANSI standard is never risky.

      --
      Mod down posts with a "Free Mac Mini/iPod" sig, they're spam!
    8. Re:Neither are correct. by LiquidCoooled · · Score: 1

      As I recall, NULL does not always == 0.
      Won't some compilers shout at you for comparing a long against a pointer?
      Doesn't it have to be casted, hence making the almost universally defined macro essential for clean compilation.

      Also, some computer systems do not use 0 as the definition of an uninitialised pointer.

      --
      liqbase :: faster than paper
    9. Re:Neither are correct. by Anonymous Coward · · Score: 0

      What if NULL is defined to a non-zero value?

    10. Re:Neither are correct. by mjprobst · · Score: 1

      According to the C FAQ, this is _not_ true; there's a whole section on NULL and pointers. One can always compare against zero in a pointer context, and the compiler knows how the null pointer is represented. It is indeed true that the null pointer can be something besides a bit pattern of all zeroes on some machines, but in a pointer context 0 is seen as just an abbreviation for "whatever the null pointer is represented as".

      However setting NULL=0 or ((void*)0) can be useful if one is not comfortable using bare zeroes in pointer-related code; it's a matter of style.

    11. Re:Neither are correct. by RocketJeff · · Score: 1
      However, this is predicated upon the fact that the system defined NULL is 0
      0 (zero) is always equivalent to a NULL pointer in ISO standard C (and, by extension) ISO standard C++. it doesn't matter what the 'real' NULL pointer value is (I remember that some odd-ball architecture uses a non-zero value) - the standard requires 0 to test as equal to NULL.
    12. Re:Neither are correct. by hpa · · Score: 2, Interesting

      if (0!=ptr) is a hideous abortion, because it's not readable.

      Also, your statement that "relying on NULL to be compatible with all pointer types is risky" is just plain wrong.

    13. Re:Neither are correct. by mooingyak · · Score: 1

      If you've got overloaded functions, you're not writing C anymore.

      --
      William of Ockham had no beard. The most likely explanation is that it was chewed off by squirrels every morning.
    14. Re:Neither are correct. by Aeiri · · Score: 1

      Putting the value on the left side prevents == VS = mixups

      == VS = mixups (for me at least) have nothing to do with not knowing WHERE they belong. I just either hit the key too softly or typing too fast to realize what I just typed. Putting the value first wouldn't help that.

    15. Re:Neither are correct. by neil.pearce · · Score: 1

      You are correct. It's quite amazing how many people refuse to believe this and come out with crap such as "I used a machine in 1985 where NULL was 7" and such like.

      NULL is ALWAYS 0

      The null pointer (which is a different thing altogether) can be any bit pattern.

      Where the compiler sees a 0 in a pointer context, it gets replaced with the null pointer.

      A situation where you must explicity put a null pointer (instead of just 0 and relying on the compiler) would be to a variable args function, since the compiler doesn't know if you mean "int 0" or a null pointer.

      Check your man pages for examples using execl etc... functions, they'll aways be shown with explicit (char*)0's on the end. That's why.

    16. Re:Neither are correct. by Cthefuture · · Score: 2, Insightful

      I have seen this syntax used sometimes. Personally, I find it difficult to read. The problem is that you have reversed the logic in a LISP-like way. There is a reason LISP is not mainstream, think about it.

      IMHO, a good programming language is an extension of your thought processes. No current language is particularly great, but some are better than others because they work more like the way we think. This is a huge part of Object-Oriented programming, its purpose is mostly grouping and categorizing things. That's what humans do, group and catagorize. Note that I'm not saying OOP is the answer to everything, I believe all programming idioms have there place. However, there are good reasons why OOP got popular.

      When I'm working with a particular variable, in my head I'm thinking "I need to check this variable against NULL" (ie. variable == NULL). I absolutely do not think "NULL, what kinds of things are NULL." That would be backwards.

      Anyway, back to the optimization thing. I use things like if (!ptr) all the time but not for optimization purposes. People use that test so often that I don't think anyone thinks it's confusing. Sometimes I will use the more verbose test if the code is particularly complex but the thought of it being less optimal never entered my mind because even if it were slower, it would be such a small difference that it wouldn't matter.

      Too often I see people "optimizing" code that doesn't need to be optimized due to the fact that there are other places in the code that are much, much slower making the optimization such a small benefit that there is no reason to do it in the first place.

      On the other side of that, I see people ignoring optimization thinking that if they need to make it faster they can worry about that later. Then after 10,000 lines of code they realize that the system is too slow and there is nothing they can do about it because of bad (slow) design decisions made throughout the process.

      --
      The ratio of people to cake is too big
    17. Re:Neither are correct. by Anonymous Coward · · Score: 0
      Mod parent down -- false.

      The standard allows (requires?) NULL to be "0" and allows ((void*)0) to be something entirely different from null.

    18. Re:Neither are correct. by Anonymous Coward · · Score: 0

      Mod parent up. It's the only post making sense around here!

    19. Re:Neither are correct. by kevpie · · Score: 1

      Anyone consider negative ptrs and 1's compliment -0 ?

      In 1's complement can you have -NULL or a NEGULL or would you a NEGANULL?

    20. Re:Neither are correct. by Anonymous Coward · · Score: 0

      You're correct that NULL does not always equal 0 (Formally, NULL is a null pointer constant, which is defined as an integral constant with value 0, or such an expression cast to void*; in practice this makes NULL 0 or ((void*)0).)

      But you're wrong about the comparison of a long to a pointer, and not just because 0 is an int, not a long. In such a comparison, a null pointer constant is allowed to be compared to a pointer, and 0 is a null pointer constant.

      Using NULL is no more safe than using 0, because NULL is allowed to be a plain old zero.

      Inevitably this is the time when someone pipes up "but a null pointer doesn't have to be all bits zero, therefore you're wrong". Correct on the first part, incorrect on the second. Null pointers needn't be all bits zero, but that doesn't matter, because when the compiler sees you use 0 in a pointer context, it knows to convert it to whatever a null pointer is on the target architecture. This is just how C works.

    21. Re:Neither are correct. by fitten · · Score: 1

      What compiler are you using that doesn't issue a warning for the '=' used in an if statement?

      This assumes the programmer is actually paying attention to the output of the compiler. Many I know simply compile and if the 'make' succeeds, it must be good. Personally, I don't like to have any warning or error output in my code.

    22. Re:Neither are correct. by Anonymous Coward · · Score: 0

      While defining your own NULL is supremely stupid (just include the proper header), there's no harm in assuming NULL is 0. Using 0 wherever you can use NULL is perfectly fine. The only thing you know about NULL is that it is 0 or (void*)0 (Or something awfully similar, like 0L).

      The whole point being, a portable program can use 0 wherever it could also use NULL. This is regardless of the representation of a null pointer is on the actual hardware.

      I'll say it once more: NULL must be 0 or (void*)0, or some functional equivalent like 0L. It may not be a value like (void*)0xdeadbeef. Yes, regardless of the representation of a null pointer on the actual hardware.

    23. Re:Neither are correct. by Anonymous Coward · · Score: 0

      Mod parent down -- false.

      The standard does allow NULL to be 0, but it also allows NULL to be ((void*)0). 0 and ((void*)0) are different from each other, yes, but they are both null pointer constants, and therefore legal values for NULL.

    24. Re:Neither are correct. by DunbarTheInept · · Score: 1

      I cringe whenever I see code that says "if( x == true )", becuase I wonder, "but what if X = 2, or 3, or -1??, those values are not false, but this code will think they are.

      Since the smallest addressable space is NOT a single bit, but rather is an entire byte, the whole notion of a boolean type that can only be zero or one is a bit of a lie. I much prefer to use a mapping that catches the entire value space, leaving no such thing as an "undefined" value. So, a boolean should be "zero = false, everything else = true", as opposed to "zero = false, one = true, everything else = a gotcha that varies depending on if the programmer wrote positive checks or negative ones."

      --

      Don't label something "offtopic" unless you know the topic well enough to tell what's on topic.

    25. Re:Neither are correct. by LiquidCoooled · · Score: 1

      I realised this as well, and have infact posted something very similar in another reply.
      The compiler simply translates a "0" in a pointer context up to be an uninitialized memory pointer on whichever the target system is (whether that is or is not == 0 is irrelivent to the code).

      --
      liqbase :: faster than paper
    26. Re:Neither are correct. by LinuxInDallas · · Score: 1

      The C/C++ from IAR for the MSP430 doesn't. And that's a $3000 compiler. Learned that the hard way.

    27. Re:Neither are correct. by HeghmoH · · Score: 1

      Actually, it would help. For example:

      if(x = 0)

      This will compile, and if your compiler is evil, it may not even warn. (Although if it doesn't, you should either fix it or fire it.)

      if(0 = x)

      This won't compile, because 0 is not an lvalue. However, the correct way to prevent this error is to get the compiler to tell you about it any time it happens, not to contort your code.

      --
      Mod down posts with a "Free Mac Mini/iPod" sig, they're spam!
    28. Re:Neither are correct. by Anonymous Coward · · Score: 0

      No, a '0' in pointer context is a *null* pointer, not an uninitialized memory pointer. A null pointer is different than any value that a pointer pointing somewhere in memory may have.

    29. Re:Neither are correct. by Anonymous Coward · · Score: 0

      What about SEAGULL, then?

    30. Re:Neither are correct. by Anonymous Coward · · Score: 0

      Well, there are languages (including C99) that have a real boolean type. In this case, comparing to true is acceptable.

    31. Re:Neither are correct. by DunbarTheInept · · Score: 1

      I still don't care for them, because I know that what they are trying to do is not actually supported by the hardware, and is therefore inefficient. The hardware supports booleans that are zero versus nonzero, with instructions like jump if not zero and jump if zero, that all machine languages use. To force a boolean type down into just being 1 or 0 requires that the compiler insert extra code to mash the numbers down into only those two choices - the machine language equivilent of:

      if( actual_value_behind the scenes ) // is nonzero
      { value_the_high_level_program_sees = 1;
      }

      --

      Don't label something "offtopic" unless you know the topic well enough to tell what's on topic.

    32. Re:Neither are correct. by Anonymous Coward · · Score: 0

      1. In C, true and false are not keywords.

      2. In GCC's implementation of C++, NULL is a keyword that can be implicitly casted to any type of pointer. This is necessary because unlike C, C++ cannot implicitly cast void pointers. Thus (void*)O does not work for C++.

    33. Re:Neither are correct. by dadragon · · Score: 1

      What compiler are you using that doesn't issue a warning for the '=' used in an if statement?

      IIRC, gcc doesn't if you do something like this:

      if((ptr = malloc(x))==NULL) ...;

      --
      God save our Queen, and Heaven bless The Maple Leaf Forever!
    34. Re:Neither are correct. by Profane+MuthaFucka · · Score: 1
      --
      Fascism trolls keeping me up every night. When I starts a preachin', he HITS ME WITH HIS REICH!
    35. Re:Neither are correct. by Arch+D.+Bunker · · Score: 1

      No, it's not a matter of style. NULL is only guaranteed to represent a "zero" pointer for pointers to DATA types. For "zero" FUNCTION pointers, you must use the literal 0. _Not_ NULL. Because a function pointer can be wider than a data pointer (eg. certain segmented memory models on the x86 and so forth).

  8. Bad example by nurd68 · · Score: 0, Redundant

    if(!ptr) is equivalent to if(ptr == 0)

    The problem is that there is nothing that says that NULL must be 0. Potentially, one could define NULL to be something else - like -1. Therefore, one should always use if(ptr == NULL).

    1. Re:Bad example by hpa · · Score: 2, Insightful

      Bullshit.

      Read the C standard about the definition of a null pointer constant.

    2. Re:Bad example by Webmonger · · Score: 1, Redundant

      I can't say whether the NULL macro is formally defined, but the null pointer is always 0, even if the bitwise machine representation is different.

    3. Re:Bad example by Anonymous Coward · · Score: 0

      Well, this is plain wrong... A constant zero in pointer context always *is* a null pointer, regardless of its bit pattern. The only reason NULL exists is for stylistic reasons, and is defined to a constant '0' or '0' cast to (void *). Questions 5.2 and 5.4 in the comp.lang.c FAQ are relevant... http://www.faqs.org/faqs/C-faq/faq/

    4. Re:Bad example by Stavr0 · · Score: 1
      NULL is a macro -- (void *) 0

      Hopefully noone has #undef'd it in the code base. Thing is you can never be sure. Also there's some issues about ill-defined function protypes that can break.

      Ahh. I love a good C anal-retentive flamewar to finish a work week. ;-)

    5. Re:Bad example by Pr0xY · · Score: 1

      all systems that have null defined as "(void *)0" are technically broken... C and C++ both don't allow assigning a void * to a function pointer (though many allow this as an extension. So if NULL were defined as you said. technically there would be no standard conforming way to write:

      int (*f_ptr)(void) = NULL;

      it _should_ be just plain "0"

      proxy

    6. Re:Bad example by DShard · · Score: 1
      A lot of banter both ways here so just to clear this up... according to C99 section 6.3.2.3 Pointers:
      [#3] An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant.46) If a null pointer constant is assigned to or compared for equality to a pointer, the constant is converted to a pointer of that type. Such a pointer, called a null pointer, is guaranteed to compare unequal to a pointer to any object or function.
      [#4] Conversion of a null pointer to another pointer type yields a null pointer of that type. Any two null pointers shall compare equal.
      then
      46) The macro NULL is defined in as a null pointer constant; see 7.17
      Notice that NULL is a macro and not a token so can be changed and still be compliant code, just not friendly.
  9. write clearer code first by Deadbolt · · Score: 1, Redundant
    Unless your benchmarks show that writing:
    if (!ptr) { ...
    saves you significant time/size from using:
    if (ptr == NULL) { ...
    write the clearer code, which is the second option.
    --
    "Honey, it's not working out; I think we should make our relationship open-source."
    1. Re:write clearer code first by JustNiz · · Score: 1

      I disgree.
      I think the first option is much clearer as it is more meaningful.

      Consider:
      MyClass* instance = new(MyClass);
      if (!instance) ....

      Testing for "Not an instance" makes more readable sense to me than testing for the case that a pointer to my instance happens to equal a particular value (even NULL).

    2. Re:write clearer code first by hpa · · Score: 2, Informative
      The former is a lot more concise, and conciseness helps getting the *big* concepts down.

      Anyone with any familiarity with C will consider the latter form unnecessarily more verbose, and therefore less clear.

      There is one exception to that, and that is when "ptr" is in fact a complex expression that it isn't obvious at a glance is a pointer expression. In that case, == NULL or != NULL spells out to the reader of the code "oh, and by the way, it's a pointer." That is the ONLY reason to write this for clarity.

      There is a whole category of "bad commenting" in which comments left that are only useful to someone who don't know the programming language actually makes the code a lot harder to read. A comment like:

      a += 2; /* Add two to a */

      ... is not helpful in any shape, way or form, and just provides mental clutter.

    3. Re:write clearer code first by oolon · · Score: 1

      There are good reasons for doing if (!ptr) paticularly if your using c++. NULL is a void * typedef and normal comes from a 32 bit type, this can produce unexpected problems. It is considered better these days to let the compiler to any type conversion for you, and to not use NULL at all. So the use of (ptr==0) or (!ptr) is better.

      better example is for code use is...

      ++c or c++ the former oftain saves a store and return from the stack, as c++ require the orginal value to be returned to the lhs rather than the post increment value, bet most people write c++!

      James

    4. Re:write clearer code first by Anonymous Coward · · Score: 0

      The clearer code is the shorter code. They are equivalent and anyone who writes C for more than a few days knows that !ptr is equivalent to ptr == NULL. And with !ptr, there's no chance of an == = mixup.

    5. Re:write clearer code first by ecklesweb · · Score: 1

      I'm pretty famliar with C and I have the opposite opinion. Things like if(!ptr) bug the crap out of me because you're implying that a pointer is equivalent to or comparable to an int.

      Moreover, it drives me up the wall to see code like ptr = 0; to set a pointer to NULL. C is error prone enough without abusing the overlap between 0, \0, and NULL.

      Then again, my job is to fix bugs in production C code, so the only code I ever work with is a) always buggy and b) usually poorly written (well...until I get done with it, that is).

    6. Re:write clearer code first by lgw · · Score: 1

      It's all about idiom. If you're used to seeing (!ptr) that's more clear. If you're used to seeing (ptr==null) that's more clear.

      I prefer (!ptr) as I often overload the ! operator in C++ classes to tell me when the class is valid for use, so (!ptr) is a common idiom. In a shop where many people do that, it's more clear. In a shop where I'm the only one, it's obfuscation.

      --
      Socialism: a lie told by totalitarians and believed by fools.
    7. Re:write clearer code first by DunbarTheInept · · Score: 2, Insightful

      I agree that you should write the more clear form, and damn the optimization. But I disagree that the second form is the more clear one. The first one reads as "if not pointer", which very consisely and completely conveys the meaning that is intended, which is "If this thing isn't really a pointer to anything."

      The problem comes from the fact that some functions that return integers do so in a way that has the inverse of the intuitive boolean interpretation. (Zero means true). One example is strcmp(), I'd much rather see if( strcmp(s1,s2) == 0 ) than if( ! strcmp(s1,s2) ), since the boolean version has 100% inverted meaning from what it looks like. System calls (man page 2) typically have the same problem. It's not that the calls themselves are bad (they have good reasons to return zero for success - becuase they have more than one kind of failure), but that the people using them should never have gotten into the habit of using inverted boolean symbology to interpret them in their code.

      If an integer doesn't behave like a boolean, then just treat it as an integer. Don't take advantage of the lose typing of C to treat it like a boolean that means the opposite of what it means.

      --

      Don't label something "offtopic" unless you know the topic well enough to tell what's on topic.

    8. Re:write clearer code first by Detritus · · Score: 1
      The constant 0 is handled as a special case in the definition of the language. Which means that:

      char *p = 0;
      p = 0;
      if (p == 0) ;
      if (!ptr) ;

      are all valid and portable. The programmer should understand that the compiler will replace 0 with whatever is appropriate for the target system.

      --
      Mea navis aericumbens anguillis abundat
    9. Re:write clearer code first by Malc · · Score: 1

      Whilst we're at it, it's good practice to do:

      if (NULL == ptr) { ...

      Get in to the habit of putting the variable second and you're less likely to have problems due to a typo that does an assignment.

    10. Re:write clearer code first by Rew190 · · Score: 1

      You really don't think calling a class variable "instance" might hurt readability with any sizable program with muliple instances of classes?

    11. Re:write clearer code first by Rew190 · · Score: 1

      The former example reads as "If not pointer..."

      The latter reads "If pointer is null..."

      Although I can read both as easily, I think the second example is more intuitive and more difficult to mess up (especially given languages like java, which many students/future coders are being brought up on). Also, because of the exception that you brought up (about ptr possibly being complex), I use "== null" just because it's uniform across the board. This is just a personal preference though. Coders who can't tell the difference probably shouldn't be working in C anyhow, right?

      Totally agree with you on the second half of your post, by the way.

    12. Re:write clearer code first by clard11 · · Score: 1

      You beat me to it, but this is common practice and a good tip - I was surprised to see the original example written the other way round.

      --
      catch (ModDownException mde) {post.modUp("Interesting")}
    13. Re:write clearer code first by JustNiz · · Score: 1

      *sigh* Its just a fragment of DUMMY code to underline my original point. As such, the names are arbitrary becuase most people wouldn't be anal enough to be concerned this would actually get copied and used somewhere.

    14. Re:write clearer code first by CProgrammer98 · · Score: 1

      What;s the beef?

      They're all the same..

      grep NULL /usr/lib/*.h shows that
      there's several standard include files that include lines like
      #define NULL 0

      --
      And the people shall be oppressed, every one by another, and every one by his neighbour Isaiah 3:5
    15. Re:write clearer code first by CProgrammer98 · · Score: 1

      My bad... hat should have been /usr/include/*.h of course.

      --
      And the people shall be oppressed, every one by another, and every one by his neighbour Isaiah 3:5
    16. Re:write clearer code first by Rew190 · · Score: 1

      Well right, I caught that, but we were talking about large, production-value programs.

    17. Re:write clearer code first by Bill+Dog · · Score: 1
      When I first glanced at that, I got tripped up for a split sec on "if (!instance) ....". I thought, hmm, I wonder why that class is overriding operator bool. I find the following clearer, in increasing clarity:

      if ( instance != NULL ) ...
      if ( ! pInstance ) ... // (I subscribe to a "sane set" of Hungarian notation)
      if ( pInstance != NULL ) ...

      --
      Attention zealots and haters: 00100 00100
  10. You're asking the wrong crowd by CarrionBird · · Score: 1

    Prepare for 93242.5 posts telling you to use java or perl or ada instead.

    --
    Free Mac Mini Yeah, it's
    1. Re:You're asking the wrong crowd by slavemowgli · · Score: 1

      Ada? o.o I can understand Java and Perl, yes, but who on earth still uses or recommends Ada, especially on Slashdot?

      --
      quidquid latine dictum sit altum videtur.
    2. Re:You're asking the wrong crowd by Zphbeeblbrox · · Score: 1

      you should use perl instead. :-) sorry I couldn't resist.

      --
      If you see spelling or grammatical errors don't blame me. I tried to preview but IE here at work borked the CSS
    3. Re:You're asking the wrong crowd by karniv0re · · Score: 1

      Get it right. This is Slashdot, where Python is god.

    4. Re:You're asking the wrong crowd by LakeSolon · · Score: 2, Insightful

      You do realize slashdot is written in perl, yes? Or have you not noticed the contents of the URL, your own comment for example http://ask.slashdot.org/comments.pl?sid=140256&cid =11781397

      ~Lake

    5. Re:You're asking the wrong crowd by sconeu · · Score: 1

      with SLASHDOT;
      package BASHING is new SLASHDOT.BASH(LANGUAGE => ADA);
      with BASHING; use BASHING

      --
      General Relativity: Space-time tells matter where to go; Matter tells space-time what shape to be.
    6. Re:You're asking the wrong crowd by slavemowgli · · Score: 1

      I actually prefer to bash Python, myself. Ada is merely obsolete; Python is an abomination. :)

      --
      quidquid latine dictum sit altum videtur.
    7. Re:You're asking the wrong crowd by kclittle · · Score: 1
      I kneel and genuflect...

      --
      Generally, bash is superior to python in those environments where python is not installed.
    8. Re:You're asking the wrong crowd by thedustbustr · · Score: 1

      Python is god off slashdot, too.

      --
      This sig is false.
    9. Re:You're asking the wrong crowd by Anonymous Coward · · Score: 0
      no no no... you've got to build a pdp/11 out of tinker toys and install FORTRAN or COBOL from punch. No, don't use the hubs for ... MOVE!

      Smoedya Il'l figrue otu teh previwe btuton

    10. Re:You're asking the wrong crowd by Anonymous Coward · · Score: 0

      Only if he's running on the desktop...on an embedded platform I would say optimize as much as you want/can since handhelds for the most part are not quite to the point of having tons of excess processor time, although some are getting darn close.

      I'd still say using C or other compiled-to-native coding is the best as long as you don't have to sacrifice portability or ease of maintenance...

      OH YEAH! USE PERL d00D#!

    11. Re:You're asking the wrong crowd by Anonymous Coward · · Score: 0

      Python blows goats...

      use strict;

    12. Re:You're asking the wrong crowd by kbielefe · · Score: 1
      I do.

      Don't even get me started on why. Just let me say that I currently use Ada, C, and Perl approximately equally and consider myself fluent in all 3. Guess which one more frequently works right for me the first time by a significant margin? Guess which one I spend the least time debugging other people's code in?

      --
      This space intentionally left blank.
    13. Re:You're asking the wrong crowd by slavemowgli · · Score: 1

      Actually, if I didn't know you're probably referring to Ada, I'd guess that the answer to both questions is "Perl".

      Of course, technically, I spend the least time debugging other people's Ada code, too (as opposed to other people's C and Perl code), but that's just because I never debug any Ada code at all...

      --
      quidquid latine dictum sit altum videtur.
    14. Re:You're asking the wrong crowd by bill_wye · · Score: 1

      Actually, my friend's knowledge of Ada is the basis for him getting work in Canadian and US Aerospace-related fields.

      Obsolete or not, it's still used.

      --
      The nose doesn't cause the tail.
    15. Re:You're asking the wrong crowd by slavemowgli · · Score: 1

      In its own specialized field, yes - IIRC, this is the field that Ada actually was developed for. It's not a language that's generally-used outside of that field, though - and, for that matter, there are many languages that are still alive in their niches. COBOL and Fortran are two that immediately come to mind, but I'm sure there several others.

      --
      quidquid latine dictum sit altum videtur.
    16. Re:You're asking the wrong crowd by kbielefe · · Score: 1
      That's because you haven't given Ada a fair try in a large project yet. I'd choose Perl too between Perl and C.

      Never underestimate the power of inertia. Without it, no one would be using Windows or C.

      --
      This space intentionally left blank.
    17. Re:You're asking the wrong crowd by default+luser · · Score: 1

      I use ada on a daily basis, and I've only got one problem with it:

      -- say you declared yourself an array and
      -- procedure with the same name...

      type Array_Type is array (SIZE) of Integer;
      Something : Array_Type;

      procedure Something ( Input : Integer );

      -- And now you try to tell me what this does,
      -- because it could be a call to procedure
      -- Something, or indexing into array Something:

      Something (I);


      Sure, there's not a compiler in hell that would let you get away with this, but that's not the point. The point is, any language that uses
      parenthesis to fill the role of both procedure argument bounds AND array index brackets is retarded.

      If you are tying to interpret code you've inherited, you are left at the mercy of the creator in determining if Something(I) is a procedure or an array, especially if the type itself is buried somewhere. If they don't name things specifically to convention, the usage is unclear.

      Now THAT is retarded.

      But that's really the only problem I have with ada. The rest of the language is quite nice.

      --

      Man is the animal that laughs.
      And occasionally whores for Karma.

    18. Re:You're asking the wrong crowd by MBraynard · · Score: 1
      Ahoy -

      You do the referral in my sig and I will do yours - just shoot me an email when you have done it at mattatbraynarddotcom.

      I already got the Ipod and Xbox free. Good luck.

  11. everything by miu · · Score: 1

    I trust the compiler to optimize almost everything. Use a profiler, since hand optimized code is more difficult to code correctly and more difficult to maintain you should only do it when it matters.

    --

    [Set Cain on fire and steal his lute.]
    1. Re:everything by lgw · · Score: 1

      Compilers can rarely optimize a bad algorithm. To veteran programmer, a poor algorithm is unclear because it makes one wonder "why didn't he do it the obviously faster way, what weird corner case is this extra work necessary for?". Well, unless one is used to fixing crap code, of course.

      --
      Socialism: a lie told by totalitarians and believed by fools.
    2. Re:everything by WoodstockJeff · · Score: 1
      I trust the compiler to optimize almost everything.

      It is important to understand any automated optimizations in use. Most are safe. Some have dire consequences under certain circumstances. Compilers only understand the code presented to them, not the context in which it will run. A common example is loop-invarient code migration. 99.9% of the time, it's great. Until it optimizes your device driver polling loop to remove the device read from the loop. (but whe all know we shouldn't be writing polling loops anymore, right?)

      I agree with those who say strive for a better algorithm first, then profile it to see where the improvements would do the most good, after you have it correct.

    3. Re:everything by miu · · Score: 1
      That is why the STL is so great, it lets programmers who are not computer scientists easily select the correct algorithm without worrying much about implementation.

      If you are doing a sequential search and append of a huge list in an inner loop then you have a lot more to worry about than what the compiler can optimize or not, but that is a vry different issue.

      --

      [Set Cain on fire and steal his lute.]
    4. Re:everything by miu · · Score: 1
      Well yeah, but that is what 'volatile' is for - most of the time the compiler is going to do an adequate job of optimization.

      Really most of the time I think it is best to just let the compiler do its job. If you need to tweak a build rule or work around a bug (or even change compilers), then do so - but don't go in expecting to do all the heavy lifting yourself.

      --

      [Set Cain on fire and steal his lute.]
  12. Clear & Concise Code by kwiqsilver · · Score: 4, Interesting

    It's better to write clear, legible code that saves a human minutes of reading, than complex code that might save a computer a few milliseconds of processing time per year, because human time costs more than machine time.
    Also the clear code will result in fewer misinterpretations, which will mean fewer bugs (especially when the original author is not the one doing maintenance years later), further reducing costs in dollars, man hours, and frustration.

    1. Re:Clear & Concise Code by newend · · Score: 1

      Is this because all of the IT jobs are going to be going to India? Do we really want to make it easy on them =P

    2. Re:Clear & Concise Code by StillNeedMoreCoffee · · Score: 1

      And it is also true that simple code is easier to optimize automatically and programming induced optimization can prevent the compiler from doing the best job of optimization.

      So clear simple code can have two benefits.

    3. Re:Clear & Concise Code by BESTouff · · Score: 1

      In modern India, machine time costs more that you !!

    4. Re:Clear & Concise Code by Anonymous Coward · · Score: 0

      human time costs more than machine time

      Hm, don't be so quick to assume that.

      Say you're working on some widely used software. You write strange but efficient code and it costs a few hundred dollars for the next guy to figure it out. You write clear but inefficient code and it costs millions of people $20 more each for more powerful hardware. Which is more expensive?

      That said, I'm the next guy, and the code is neither pretty nor efficient...

    5. Re:Clear & Concise Code by dodobh · · Score: 1

      But if you can save the computer a few seconds of time, those seconds add up over the lifetime of the program.

      Remember that your program can have many more users than programmers, and their time is worth something too.

      --
      I can throw myself at the ground, and miss.
    6. Re:Clear & Concise Code by DaTroof · · Score: 1

      It's better to write clear, legible code that saves a human minutes of reading, than complex code that might save a computer a few milliseconds of processing time per year, because human time costs more than machine time. Also the clear code will result in fewer misinterpretations, which will mean fewer bugs (especially when the original author is not the one doing maintenance years later), further reducing costs in dollars, man hours, and frustration.

      You raise a good point, but one thing to remember is that programmers are often competing with other programmers' machine time, not other companies' human time. If one company develops an application that can process a given set of data in an hour that takes another company's application a day, the first company has an advantage.

  13. Compile?? by unixsavant · · Score: 0

    Who compiles code anymore? Between Perl, PHP and Shell, I get everything done that I need too!

    1. Re:Compile?? by koreaman · · Score: 1

      And it's really, really slow.

    2. Re:Compile?? by Anonymous Coward · · Score: 0

      I get everything done that I need too!

      Yeah, like your laundry and the dishes, while you're waiting for the damn thing to finish running.

  14. NULL not always 0 by leomekenkamp · · Score: 2, Insightful

    Aren't there machines out there where the C compiler specifically defines NULL as value that is not equal to 0? I recall reading that somewhere, and that was my reason for using ==NULL instead of !. My C days are long gone though...

    --
    Wenn ist das Nunstueck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput.
    1. Re:NULL not always 0 by camcorder · · Score: 1

      NULL is never equal to 0, if you talk about C.

    2. Re:NULL not always 0 by Anonymous Coward · · Score: 0

      Yes. But these are mostly ancient, obsolete platforms.

    3. Re:NULL not always 0 by HeghmoH · · Score: 3, Informative

      NULL isn't necessarily equal to 0 at the machine level. However, at the language level, 0 is always interpreted exactly the same as NULL if it's being converted to a pointer, and vice versa. This is explicitly spelled out in the C standard, so any compiler that doesn't obey this is breaking the standard. Saying !ptr and ptr == NULL is always identical on a conforming compiler (which they pretty much all are).

      --
      Mod down posts with a "Free Mac Mini/iPod" sig, they're spam!
    4. Re:NULL not always 0 by bradkittenbrink · · Score: 1

      JoeBuck would seem to say no here. Although he's not the most insightful sports broadcaster in my opinion and I bet he's even less knowledgable about C compilers.

    5. Re:NULL not always 0 by Eryq · · Score: 1

      IIRC, the machine-level representation of NULL is not guaranteed to have *all bits* set to zero. However, I think the ANSI C standard specifically says that a NULL pointer will always be == to integer 0. IOW, your compiler will do the right thing.

      Look at the ANSI standard to be sure.

      --
      I'm a bloodsucking fiend! Look at my outfit!
    6. Re:NULL not always 0 by LiquidCoooled · · Score: 2, Informative

      Your right about none zero memory pointers (I was just re-reading a FAQ compiled from the K&R bible).

      BUT as part of an C compiler, using a "0" in a pointer context will always compile to a null pointer on the target system.

      The only problems with zeros comes from the cast applied when passing parameters, and in such cases, even a NULL definition may require explicit casting.

      --
      liqbase :: faster than paper
    7. Re:NULL not always 0 by Anonymous Coward · · Score: 1, Informative

      Well, just to be a bit anal, the standard does *not* guarantee that a NULL pointer will be == to an integer 0. It guarantees that it is always == to a *constant* 0, *in the source*. So, this will not work:

      int main(void) { int a = 0; int *p = NULL; if (p == (int *)a) printf("Equal!\n"); return 0; }

    8. Re:NULL not always 0 by Malc · · Score: 2, Informative

      Maybe you've been listening to C++ people? Stroustrup certainly has a chip on his shoulder about NULL:

      5.1.1 Zero

      Zero (0) is an int. Because of standard conversions, 0 can be used as a constant of an integral, floating-point, pointer, or pointer-to-member type. The type of zero will be determined by context. Zero will typically (but not necessarily) be represented by the bit pattern all-zeros of the appropriate size.

      No object is allocated with the address 0. Consequently, 0 acts as a pointer literal, indicating that a pointer doesn't refer to an object.

      In C, it has been popular to define a macro NULL to represent the zero pointer. Because of C++'s tighter type checking, the use of plain 0, rather than any suggested NULL macro, leads to fewer problems. If you feel you must define NULL, use

      const int NULL = 0;

      The const qualifier prevents accidental redefinition of NULL and ensures that NULL can be used where a constant is required.

    9. Re:NULL not always 0 by Mattintosh · · Score: 1

      I once read through some header files from Symantec C++ version 8.6 on MacOS (old MacOS). It defined NULL like this:

      #define NULL 0

      It's kinda difficult to redefine NULL when the compiler does a wholesale find-and-replace on it before compiling (and it complained, as it should, when you tried to #define something twice).

    10. Re:NULL not always 0 by Malc · · Score: 1

      Yeah, I can't see how Stroustrup was targetting programmers when he said "If you feel you must define NULL, use [...]". For must of us we don't have a choice because it's already defined. Personally I think he's being a bit excessive.

    11. Re:NULL not always 0 by Eryq · · Score: 1


      Yes. Excellent point. I was sloppy in my reply (which is why I point people to the standard itself.)

      --
      I'm a bloodsucking fiend! Look at my outfit!
    12. Re:NULL not always 0 by Anonymous Coward · · Score: 0

      Even more fun is the newer versions of g++. They define NULL as:

      #define NULL __null

      What is __null? It's a compiler keyword which goes all the way through preprocessor and parser so the compiler knows it is meant to be anull, not a 0. It is an integral-typed constant with value 0 (as described in the standard). I'm not even sure what kind/length of integer type, but it's not a pointer.

      They do this so they can detect and warn about overloads like:

      void foo(int);
      void foo(char *);

      foo(NULL); //Calls the int overload, as per the standard

      People seem to like this warning. Of course, being a 0, you can also write

      int a=NULL

      with not as much as a warning.

      (You should never have to define NULL, or even care as to the exact definition)

    13. Re:NULL not always 0 by CProgrammer98 · · Score: 1

      Works just fine on my gcc compiler

      --
      And the people shall be oppressed, every one by another, and every one by his neighbour Isaiah 3:5
    14. Re:NULL not always 0 by CProgrammer98 · · Score: 1

      ummm yeah it is.. see the Ansi standard, and the c faq that others have pointed out

      --
      And the people shall be oppressed, every one by another, and every one by his neighbour Isaiah 3:5
    15. Re:NULL not always 0 by camcorder · · Score: 1

      As a value sure it is, but NULL is never substitude for 0 and it's in a pointer type, however 0 is in integer type. That means they are not equal, if they were they would be used as substitudes. Compilers mostly convert NULL to 0, but that can't be a programmer view, because it would lead lots of bugs in a project.

    16. Re:NULL not always 0 by drxenos · · Score: 1

      You really should read the standard sometime. Compilers don't convert NULL to anything. They never see it. Both ANSI C and C++ require NULL to be a macro and require it to be 0. Internally, a null pointer can be anything. But a value of 0, when used with pointers, always indicates to the programmer AND the compiler that it is a null pointer. NULL and 0 are equivilent.

      --


      Anonymous Cowards suck.
  15. GIGO by Skiron · · Score: 1

    The compiler will always produce asm better than a human, but you have to remember - GIGO (garbage in, garbage out).

    Make the code EASY to read and logical... 5 lines is better than trying to get it in 1 line - the compiler will still produce the same end product, anyway.

    1. Re:GIGO by Anonymous Coward · · Score: 0

      Since when do compilers produce asm better than humans?

      The whole argument behind this entire thread is that compilers do NOT produce ASM better than humans. If they did, we would not need to worry about writing cryptic code for the sake of improving the ultimate results of the translation performed by the compiler.

    2. Re:GIGO by Anonymous Coward · · Score: 0

      I've actually played around with several C compilers, and no, they do not always do better than a human writing the same assembly (though obviously they do it faster), often making questionable choices that can not be explained.

      I've often seen this "the compiler is smarter than you are" as an excuse for never using the register keyword in C, but I have actually tested this many times on multiple compilers (x86 architecture by and large) and even on maxed out optimizations they often fail to correctly identify which variables are *really* important to program speed.

      I'm not advocating everyone go back to writing in assembly (especially not x86), but don't assume the compiler will do your work for you.

      Very few compilers out there can even recognize iteration over an array for instance, so the less legible but faster hand coded pointer arithmetic will beat the compiler's version of a for loop with array subscripting 99% of the time.

    3. Re:GIGO by DCheesi · · Score: 1

      The compiler will always produce asm better than a human[...]

      Umm, no. Hand-coding in assembler is still called for in cases with extremely limited resources and complex or unusual tasks to be completed. It's just that these cases are increasingly rare as memory and processing power become cheaper and smaller.

      Still, your overall point is valid. In 99.9% of cases, readability is more important.

    4. Re:GIGO by damiam · · Score: 1
      The compiler will always produce asm better than a human

      No it won't. There are cases where a good asm programmer can get a significant speedup over the compiler. That said, 99% of the time it's not worth the effort.

      --
      It's hard to be religious when certain people are never incinerated by bolts of lightning.
  16. Code Twiddling by bsd4me · · Score: 2, Informative

    There really is no one answer to this, as it depends on the compiler itself, and the target architecture. The only real way to be sure is to profile the code, and to study assembler output. Even then, modern CPUs are really complicated due to pipelining, multilevel cache, multiple execution units, etc. I try not to worry about micro-twiddling, and work on optimizations at a higher-level.

    --

    (S(SKK)(SKK))(S(SKK)(SKK))

  17. From the "Patenting Fire" department by slipnslidemaster · · Score: 4, Funny

    I just checked the U.S. Patent office and sure enough, just minutes after your post, Microsoft patented "if (!ptr)" as a shorthand for "if (ptr==NULL)".

    Prepare to be sued.

    --


    "What the hell is an aluminum falcon?"
    1. Re:From the "Patenting Fire" department by SmokeHalo · · Score: 1

      Since MS patented it afterward, the post should be considered prior art. ;)

      --
      I'm not good in groups. It's difficult to work in a group when you're omnipotent. - Q
    2. Re:From the "Patenting Fire" department by slipnslidemaster · · Score: 0

      Microsoft cannot be bothered by such piddling consideration: http://yro.slashdot.org/article.pl?sid=05/02/22/13 10232&tid=109&tid=155

      I heard they just patented the equals sign.

      --


      "What the hell is an aluminum falcon?"
    3. Re:From the "Patenting Fire" department by Kelerain · · Score: 1

      Do you realize what this means? We simply have to patent ALL bad programing constructs! Then there will be nothing left but quality code!

      That and we can sue anyone writing sloppy code.

    4. Re:From the "Patenting Fire" department by slipnslidemaster · · Score: 0

      I'm thinking about patenting the key combination [CTRL][ALT][DEL].


      *gleefully rubs hands together*

      --


      "What the hell is an aluminum falcon?"
    5. Re:From the "Patenting Fire" department by waveman · · Score: 1

      > I just checked the U.S. Patent office and sure enough, just minutes after your post, Microsoft patented "if (!ptr)" as a shorthand for "if (ptr==NULL)".

      This is doubly ironic, because the C standard does not guarantee that if (!ptr) has the same result as (ptr != NULL). NULL does not have to be "zero" and on some strange CPUs, it actually is not zero.

      Yes that's right, the idiom if (!ptr) is not valid.

  18. Tradeoffs by Black+Parrot · · Score: 4, Insightful


    Hard to measure, but what is the tradeoff between increased speed and increased readability (which is a prerequisite for correctness and maintainability)? And if you can estimate that tradeoff, which is more important to the goals of your application?

    As a side note, it is far more important to make sure you are using efficient algorithms and data structures than to make minor local optimizations. I've seen programmers use bizarre local optimization tricks in a module that ran in exponential time rather than log time.

    --
    Sheesh, evil *and* a jerk. -- Jade
    1. Re:Tradeoffs by TheGavster · · Score: 1

      I always hear this, to optimize the algorithm not the implementation. But once you have the best algorithm, implementing it stupidly is still wasting potential speed. Shaving .00001 seconds off a loop seems inconsquential. Remember, though, that you picked a good algorithm so that in the case of millions of pieces of data, running time would be limited. By the same logic, shaving a millionth of a second off the execution time of a loop through smart code will save seconds of execution time for millions of iterations. The number of times I've seen code that calls an accessor to get a piece of data from an object for a loop boundary, when that data is never going to change, infuriates me. Call the accessor once, save the return to a local variable, and use that.

      --
      "Because Science" is one step from "Because old book". Try "Because of my experiment testing my falsifiable assertion".
    2. Re:Tradeoffs by Anonymous Coward · · Score: 0

      Bleh, just tell the compiler to inline methods and let it do it's work.

      Who says the data will *never* change...

    3. Re:Tradeoffs by StillNeedMoreCoffee · · Score: 1

      Besides some programmer optimizations prevent the compiler from doing some of its optimizations therby slowing the whole thing down.

    4. Re:Tradeoffs by Anonymous Coward · · Score: 0

      Name one. One that someone would actually do.

      It's just an excuse people who don't feel like understanding what their code actually does use to justify not bothering.

  19. Optimize at the interpreter/compiler level... by sporty · · Score: 2, Interesting

    Common idioms should be compiled away, like !x or x!=0. Uncommon idioms can't and probably shouldn't be attempted, i.e. if(!(x-x)) (which is always false). Ask your compiler maker and see if patches can be made for these types of things. 'cause if you think to do it one way, chances are, many others may try it too. It would be for their benefit to make a better compiler.

    --

    -
    ping -f 255.255.255.255 # if only

    1. Re:Optimize at the interpreter/compiler level... by Felonious+Monk · · Score: 1

      Actually the assertion that !(x-x) is always false is in and of itself false in languages that allow operator overloading. Obviously, you assumed the intrisic operation, and the compiler would certainly know the difference, but from a human standpoint, no such assumption could be made.

    2. Re:Optimize at the interpreter/compiler level... by hpa · · Score: 1

      !(x-x) can be true if x is a floating-point variable (in which case it's equivalent to isnan(x)).

    3. Re:Optimize at the interpreter/compiler level... by hanshotfirst · · Score: 1

      Umm, please tell me why my understanding is wrong here...
      !(x-x) evaluates to !(0)
      !(0) evalutes to 1, which is interpreted as true
      so.. if(!(x-x)) would always evaluate to TRUE, correct??
      Is my C memory THAT far out of whack?

      --
      Why, oh why, didn't I take the Blue Pill?
    4. Re:Optimize at the interpreter/compiler level... by CoderBob · · Score: 1

      I also am curious as to how !(x-x) is always false. X-X, if X is any integer type, should result in 0, and !0 should be the same as !false in most languages. !false should return to true.

    5. Re:Optimize at the interpreter/compiler level... by bill_wye · · Score: 1

      But this does't work for Java, the holiest of holies!

      --
      The nose doesn't cause the tail.
    6. Re:Optimize at the interpreter/compiler level... by sporty · · Score: 1

      I made a misteak. I meant to say true ;)

      --

      -
      ping -f 255.255.255.255 # if only

  20. Most people should not bother by El+Cubano · · Score: 5, Insightful

    What about code that is more complex? Now that compilers have matured over years and have had many improvements, I ask the Slashdot crowd, what they believe the compiler can be trusted to optimize and what must be hand optimized?

    Programmers cost lots more per hour than computer time. Let the compiler optimize and let the programmers concentrated on developing solid maintainable code.

    If you make code too clever in an effort to try to pre-optimize, you end up with code that other people have difficulty understanding. This is leads to lower quality code as it evolves if the people that follow you are not as savvy.

    Not only that, but the vast majority of code written today is UI-centric or I/O bound. If you want real optimization, design a harddrive/controller combo that gets you 1 GBps off the physical platter (and at a price that consumers can afford).

    1. Re:Most people should not bother by EccentricAnomaly · · Score: 1

      For a lot of in-house software user time costs more than programmer time. For example, if your app has 100 users you have to make 100 times their average salary for your time
      to be more costly.

      --
      There are 10 types of people in this world, those who can count in binary and those who can't.
    2. Re:Most people should not bother by lgw · · Score: 1

      Programmers cost lots more per hour than computer time. Let the compiler optimize and let the programmers concentrated on developing solid maintainable code.

      Sure, if you're the only one who ever uses your code. This scripting mentality bothers me. My code is used by hundreds of thousands of users. It's worth a considereable amount of my time to save each user 1 second.

      OTOH, that's not to save that trying to out-guess the compiler is a great way to save anyone any time. I do look as a disassembly of the object if I'm nervous about needing to optimize by hand, but compilers are pretty good these days.

      --
      Socialism: a lie told by totalitarians and believed by fools.
    3. Re:Most people should not bother by Anonymous Coward · · Score: 0

      This logic does not stop the people that overclock their computer and use it only for solitaire.

    4. Re:Most people should not bother by Anonymous Coward · · Score: 0
      For a lot of in-house software user time costs more than programmer time. For example, if your app has 100 users you have to make 100 times their average salary for your time to be more costly.

      Not quite. If there's a 2-second delay somewhere that happens to each user once a day and will take you 3 weeks to fix, then you'll most likely be told that it's not worth the effort. With 100 users, you could live with that problem for 8 years before you started ending up on the wrong side of the cost-benefit analysis. And besides, let's face it - if that problem still exists after 8 years of updates, bug fixes and OS changes, then you're probably not going to get rid of it with something as trivial as 3 weeks worth of work.

      Now, on the other hand, if there's a 2-second delay somewhere that costs the company $2K a day, you will most likely be told to fix it (and before tomorrow!), regardless of how long you estimate it would take to make the fix.
    5. Re:Most people should not bother by jsebrech · · Score: 1

      I think what the parent was suggesting is that optimization offers little pay off when it takes time away from debugging or feature development. Performance is a feature. It must be weighed against other potential features. Sometimes performance is the feature your users need most, but most likely most of the time they'll need something else more.

      I see this at work too. The software is slow, yes, but the demand for functionality from clients is much higher than the demand for performance, so performance work gets long-termed.

    6. Re:Most people should not bother by Anonymous Coward · · Score: 0

      Programmers cost lots more per hour than computer time.

      Not in India :-).

  21. The most important optimization... by slavemowgli · · Score: 2, Insightful

    The most important optimization is still the optimization of the algorithms you use. Unless under the most extreme circumstances, it doesn't really matter anymore whether the compiler might generate code that takes two cycles more than the optimal solution on today's CPUs; instead of attempting to work around the compiler's perceived (or maybe real) weaknesses, it's probably much better to review your code on a semantic level and see if you can speed things up by doing them differently.

    The only exception I can think of is when you're doing standard stuff where the best (general) solution is well-known, like sorting; however, in those cases, you shouldn't reinvent the wheel, anyway, but instead use a (presumably already highly-optimized) library.

    --
    quidquid latine dictum sit altum videtur.
    1. Re:The most important optimization... by lgw · · Score: 1

      Much as it pains me to agree with a yiffy pacifist, this is a great point. :) Most probles that *really* need hand-optimized solutions are already solved in a handy library.

      What gets annoying is when you have 5 different common solutions to your problem in one or more libraries, and have to guess which one might be optimized. I find this especially annoying in the Microsoft IDE, where the level of hand-coded optimization of common routines varies a lot.

      --
      Socialism: a lie told by totalitarians and believed by fools.
    2. Re:The most important optimization... by Anonymous Coward · · Score: 0

      There are applications in graphics as well, where you may be applying the same operation millions of times per frame. Less so with the advent of hardware T&L, but still...

  22. Language Age by clinko · · Score: 1

    The only solution to this is to TEST.

    Otherwise I go this way:

    Is the compiler older, and not designed for current coding practices?

    Think of it this way, if it were vb.net you can say isNULL(VAR) or (VAR = VBNull.Value)

    The vbnull value was recently added, while isNULL has been there forever.

    I use the VBNull.Value because the writer of the compiler was thinking about the new objects and wrote NEW code for it. isNull was probably a copy of an old coding practice.

    Long story short: Use Newer objects if you can.

  23. Your compiler by panth0r · · Score: 1

    Why not create your own compiler?

    --
    I like suggestions, but I don't like contributing towards them.
  24. Beware of habits. by SharpFang · · Score: 4, Interesting

    I got in the habit of writing "readable but inefficient" code, taking care that my constructs don't get too sophisticated for the optimizer but then depending on gcc -O3 thoroughly. And then it happened I had to program 8051 clone. Then I learned there are no optimizing compilers for '51, that I'm really tight on CPU cycles, and that I simply don't know HOW to write really efficient C code.
    Ended up writing my programs in assembler...

    --
    45 5F E1 04 22 CA 29 C4 93 3F 95 05 2B 79 2A B2
    1. Re:Beware of habits. by Felonious+Monk · · Score: 2, Insightful

      A good point, but code for embedded devices, or any code that has to interface with real-time physical processes, is really a different ball game.

    2. Re:Beware of habits. by Anonymous Coward · · Score: 1, Insightful

      Yeah, well, programming those old 8- and 16-bit CPUs in C has always been a bit of an exercise in masochism. Take cc65, the C compiler for the 6510 for an example. The only reason that thing produces working code is that it emulates a kind-of 8/16 bit machine through scads of subroutines which implement a sort of a stack machine, apart from the memory store and load operations and basic things like that. Actual code produced by it looks like piles upon piles of JSRs to the library routines.

      Then again, I wouldn't want to have to construct an optimizing compiler for an 8-bit, "one accumulator and 2 index registers" load-store architecture either...

    3. Re:Beware of habits. by Anonymous Coward · · Score: 0

      holy headaches, batman.
      usually, it's pretty darned easy to make your c code efficient (IMHO) -- it's not that high-level a language... if necessary, and you're "really tight on CPU cycles", you can use some inline assembly code for your really expensive routines... but writing everything in assembly? makes my brain hurt, just thinking about it.

      -asm_amature

    4. Re:Beware of habits. by poot_rootbeer · · Score: 1

      Ended up writing my programs in assembler...

      If you're coding for a platform where efficiency is so crucial that you have to hand-optimize every bit of performance out of your C code, you might as well just code in assembly language in the first place. Your custom-optimized C isn't going to port well to other platforms anyway, and you'll be thinking at such a low level anyway that the C language is little more than an intrusive syntax barrier to what you need to do.

    5. Re:Beware of habits. by Anonymous Coward · · Score: 0

      If are programming a uC and don't know how your C code gets converted into assembly, maybe uC programming is not for you. Frankly, uC compilers are not that complicated. Unless you know you aren't going to create a pipeline hazard with your assembly, just let the compiler figure it out. If you need to call dedicated instructions, that is another story and you can usually write a C function entirely in assembly.

    6. Re:Beware of habits. by mveloso · · Score: 1

      In this case, it really helps to be aware of the optimization basics: loop unrolling, cse, hoisting, etc. and the different addressing modes of your CPU.

      Assembly really is the way to go on these. You can get away with a whole lot of stuff in assembly. For example, most opcodes set a bunch of condition codes when you do things, and that really isn't taken advantage of by the compiler.

      One good thing if your optimizer sucks is to use the compiler as a front-end translator. Then you take the unoptimized output and optimize that.

    7. Re:Beware of habits. by m50d · · Score: 1

      As you should do. Really, assembler is sometimes the best tool for the job, and this sounds like a case where it is.

      --
      I am trolling
  25. Huh by NullProg · · Score: 4, Informative


    As a simple example, take 'if (!ptr)' instead of 'if (ptr==NULL)'.


    Both forms resolve to the same opcode. Even under my 6502 compiler.


    CMP register,val
    JNE


    Enjoy,

    --
    It's just the normal noises in here.
    1. Re:Huh by slashjames · · Score: 1, Insightful

      if (ptr==NULL) is better in my opinion. There is no gaurantee that NULL == 0 for all platforms!

    2. Re:Huh by DunbarTheInept · · Score: 4, Insightful

      Not true. Many CPUs have a unary jump-if-zero, or a jump-if-nonzero operation. Thus the comparasin step can be bypassed since you know you're comparing to zero.

      However, any compiler worth anything should find that and optimize it very easily in the case where you're comparing to a constant that evaluates to zero.

      --

      Don't label something "offtopic" unless you know the topic well enough to tell what's on topic.

    3. Re:Huh by Anonymous Coward · · Score: 1, Insightful

      That's no kind of 6502 code I have ever seen. I think you meant:

      LDA ptr
      bne $1
      lda ptr+1
      bne $1

    4. Re:Huh by tarpitcod · · Score: 1

      On the 6502 I think you could just do an LDA, and use the implicit setting of the zero flag to allow you to do your branch.

      LDA ptr
      BNE L1_not_null

      --6502 forever.

    5. Re:Huh by gatkinso · · Score: 2, Informative

      Sort of correct.

      According to the language definition, a constant 0 in a pointer context is converted into a null pointer at compile time. That is, in an initialization, assignment, or comparison when one side is a variable or expression of pointer type, the compiler can tell that a constant 0 on the other side requests a null pointer, and generate the correctly-typed null pointer value.

      Check out section 5.2

      http://www.faqs.org/faqs/C-faq/faq/

      --
      I am very small, utmostly microscopic.
    6. Re:Huh by Anonymous Coward · · Score: 0

      I don't think you tested that under your 6502 or you didn't define ptr as a (char *) as is implied by what the author said. It takes a lot more then that CMP on a 6502 to check if a (char *) == NULL!

    7. Re:Huh by PitaBred · · Score: 2, Informative

      As people said above, the language definition dictates that 0 == NULL. Mod parent idiot.

    8. Re:Huh by Anonymous Coward · · Score: 0

      Wrong. NULL is guaranteed to be 0 on all platforms. The binary representation might differ so memset(&ptr, 0, sizeof(ptr)); won't work where (void*)0 isn't represented by all binary zeros but (NULL == 0) will always be 1. See the C FAQ

    9. Re:Huh by NullProg · · Score: 1

      Agreed, bad example on my part. Mod me dumb and send me home for the rest of the day :)

      Enjoy,

      --
      It's just the normal noises in here.
    10. Re:Huh by Anonymous Coward · · Score: 0

      JNE is not 6502. I think you mean BNE

    11. Re:Huh by tarpitcod · · Score: 1

      OK, so if ptr points to char, then we have to do an indirect lda something like

      ; test that the char pointed to by ptr is null

      LDY #0 ;zero so we can use 0 offset for indirect
      LDA (ptr),y
      BNE


      ;I know those are assumptions, but we are talking 6502 here and assuming null == 0 on a 6502, and that a char uses a byte aren't unreasonable
      Nope, I haven't assembled this it's from memory... Or?

    12. Re:Huh by Anonymous Coward · · Score: 0
      There is no gaurantee that NULL == 0 for all platforms!

      Yes, there is. To quote the comp.lang.c FAQ,
      As a matter of style, many programmers prefer not to have unadorned 0's scattered through their programs. Therefore, the preprocessor macro NULL is #defined (by or ) with the value 0, possibly cast to (void *). [emphasis mine]


      Don't post if you don't know what you're talking about!
    13. Re:Huh by morcheeba · · Score: 1

      LDA ptr
      ORA ptr+1
      BNE $1 ... sorry, couldn't help myself!

      Shorter, but sometimes slower depending on expected value of ptr. Shorter code helps with the 6502 because of limited address space and limited relative branches. Of course, if I really wanted to optimize, I would have used assembly so I could take other shortcuts in the code.

    14. Re:Huh by Anonymous Coward · · Score: 0

      I prefer
      bne $register, $0, f_else
      or if there is no else
      bne $register, $0, f_endif

      either way, one instruction
      MIPS for the win!

    15. Re:Huh by Anonymous Coward · · Score: 0

      > Both forms resolve to the same opcode.
      > Even under my 6502 compiler.
      > CMP register,val
      > JNE

      So, your 6502 has a 8-bit address bus? You also seem to hint that it has address register_s_.

      That must be a weird variant of the 6502.

    16. Re:Huh by tarpitcod · · Score: 1

      We should just be glad it isn't iAPX432 assembler... Actually no -- that would rock...

    17. Re:Huh by NullProg · · Score: 1

      I know, mod me lazy, Its Friday afternoon. I meant it as a sample, not actual 6502 instructions. Good to see people still remember the CPU.

      Enjoy,

      --
      It's just the normal noises in here.
    18. Re:Huh by pyrrho · · Score: 1

      first, I like the old "bad" version.

      the argument against it that I know is that NULL is not nec cast to false, and NEITHER have to be (int)0.

      then again, I can't think of any platform that wasn't arranged so that false = 0 = NULL...

      --

      -pyrrho

    19. Re:Huh by tarpitcod · · Score: 1

      IGNORE prior post... Total brain fart.... It tests to see if the value pointed to by ptr is 0 -- sorry... TGIF!

    20. Re:Huh by Anonymous Coward · · Score: 0

      There's no JNE in 6502. Try BNE.

      In this vein, I once wanted to invent a 6502-themed salad dressing that would be unparalleled by its competitors.

      I called it Ranch Not Equal.

      tCS/BB

    21. Re:Huh by Sloppy · · Score: 1
      Heh. It was actually on the 6502 (well, the 6510) that I got into outguess-the-compiler habits. The compiler was "C Power" by Proline, and it didn't exactly generate great code. Don't get me wrong, I was glad to have any C compiler at all, but you definitely had to think about how you did things, if you wanted to maximize speed. Some people here are saying that programmer time is worth more than machine time, and that really is true when you're a professional working with modern machines. But when you're a teenager on a 1 MHz machine, spending several hours tweaking something for a 1% speedup, is totally reasonable. :-)

      One habit I got into, was to never assume the compiler could do short-circuit evaluations. Instead of writing

      if (foo && bar)
      __stuff
      I would write
      if (foo)
      __if (bar)
      ____stuff
      I still haven't really gotten over that habit, because I still used some dumb compilers in later years.

      Another unnecessary(?) habit I got into in the old days, was to try to define variables with the narrowest possible scope. Instead of, say,

      auto int foo;
      auto int bar;
      code that does stuff with foo
      code that does stuff with bar
      I'd do this:
      {
      __auto int foo;
      __code that does stuff with foo
      } {
      __auto int bar;
      __code that does stuff with bar
      }
      Note there aren't any control structures that require those braces -- they merely exist to make each scope use the same portion of stack. The idea being that the compiler probably doesn't realize when I'm "done" with i, so I might as well help it realize that it can use the same memory for both variables. (I know, I know, 64k should be enough for anyone...)

      You're probably wondering why I put "auto" in the above declarations...

      The 6502 doesn't have many registers, of course, but even so, some memory (zero page) is faster to access than the rest. Well, C Power would try to put any variable defined as register, in zero page. Now, that's a decent idea, except that it didn't correct save and restore this memory in between other function calls, so your variables could get screwed up. Furthermore, it also deviated from the standard in that it considered any variable to be register, unless you explicitly declared it as auto. This taught me to put "auto" in front of all my declarations to work around the bug. I carried this behavior forward for a few years after I left the C64, though mercifully I did eventually get over it.

      (BTW, it is so lame that I use to use underscores to show indented code on Slashdot.)

      --
      As copyright owner of this comment, I authorize everyone to defeat any technological measure which limits access to it.
    22. Re:Huh by Anonymous Coward · · Score: 0

      Furthermore, !ptr is defined as beeing ptr!=0, which is defined to be exactly equal to ptr!=NULL (the null pointer is 0 in a pointer context).

      Hence, the original example is stupid.

      Furthermore, I find !ptr to be more readable than !=NULL. I parse it as "if there is no ptr" which is easier to understand.

      Last, using ptr!=NULL means also using ptr==NULL, for the sake of consistency, which sometimes lead to the ptr=NULL typo (catched by modern compilers).

      Anyhow, submitter is not a great C programmer...

    23. Re:Huh by Guy+Harris · · Score: 1
      However, any compiler worth anything should find that and optimize it very easily in the case where you're comparing to a constant that evaluates to zero

      ...such as a null pointer constant, in most C implementations. (There's no guarantee that a null pointer constant is implemented as a value all of whose bytes are zero, but on most implementations - probably including the 6502 C implementation in question - it is.)

    24. Re:Huh by Guy+Harris · · Score: 1
      the argument against it that I know is that NULL is not nec cast to false, and NEITHER have to be (int)0

      1. There's no such thing as "false" in C. !x is equivalent to x == 0. See the comp.lang.c FAQ item about this.
      2. I'm not sure what you mean by "be (int)0", but note that, regardless of how a null pointer is represented in a particular C implementation, comparing a pointer against 0 is interpreted as comparing it against a "null pointer constant"; see the comp.lang.c FAQ item about this.

      Here's all the items about null pointers in the comp.lang.c FAQ.

    25. Re:Huh by CProgrammer98 · · Score: 1
      the argument against it that I know is that NULL is not nec cast to false, and NEITHER have to be (int)0.

      Ummmm... Wrong! Go read your ANSI C standard. NULL == 0 == false by definition. See C FAQ, Q5.2

      --
      And the people shall be oppressed, every one by another, and every one by his neighbour Isaiah 3:5
    26. Re:Huh by NullProg · · Score: 1

      Sorry to respond to my own post. First, thanks to everyone who responded, glad to still see the 'Art of Assembler' still alive. Second, I did not intend for the Psudo code to be interpreted as 6502. Just a generic example of LOAD,COMPARE,JUMP. Which is what the original submitters two samples would have been compiled to.

      To all those who wish to deride 'C', they can do so. When their language runs on the Mainframe in the back to the 64k Point of Sale in the front.

      Enjoy,

      --
      It's just the normal noises in here.
    27. Re:Huh by Krach42 · · Score: 1

      You mean basicly, like?

      bne r0, r3, target

      Which, would be the chosen code for either if(ptr == NULL) or if(!ptr)

      The only way you could entirely eliminate a compare would be on an architecture with auto-flag maintenance with tracking of the values. Thus, your code:

      ptr = ptr & 0xffff0000;
      if (ptr == NULL) {

      }

      on an x86 processor should result in the assembly:

      movl %eax, ptr
      andl %eax, $0xffff0000;
      jnz _skip ...
      _skip:

      This being the only situation where a check can be entirely removed. Given the code:

      ptr = malloc(sizeof(object));
      if (ptr == NULL) {

      }

      You would require a compare anyways as there is no way to be entirely certain that the flag values contained in the flag register are consistant with the value of ptr. Thus, one would still need to perform a orl %eax, %eax in order to bring the flags into an assured consistence before performing the jnz.

      On any architecture with a combined compare and branch, the issue is entirely moot, as if(!ptr) could not be more optimizably rendered as anything but a compare and branch if (not) equal.

      Basicly, your arguement that the existance of a conditional jump/branch on zero/not-zero instruction in any architecture having an impact as to the usefullness of if(!ptr) vs. if(ptr == NULL) is ill-founded. There is nothing in the existance of any such instruction (unless copled with a flag status upon arithmetic actions, which are not contained in a non-inlined subroutine) that would provide any benefit to one choice as to another.

      People today think too often that compilers and optimizers are stupid, (with some good reason if they're old enough programmers, who were not able to trust their compilers) and it frustrates me. Compilers now-a-days are awesome tools. Trust them, don't try to out-think them most times.

      --

      I am unamerican, and proud of it!
    28. Re:Huh by windwaker · · Score: 1

      That isn't 6502 code, as the others pointed out. In 6502, you'd have something that would branch on a byte in RAM being something.

    29. Re:Huh by pyrrho · · Score: 1

      good point

      --

      -pyrrho

    30. Re:Huh by Anonymous Coward · · Score: 0
      However, any compiler worth anything should find that and optimize it very easily in the case where you're comparing to a constant that evaluates to zero.

      Indeed, equating ptr!=NULL and !ptr is one of the easiest tasks that an optimizing compiler will be called on to do. It just requires static analysis. After you have parsed into an abstract syntax tree and done your standard semantic analysis (type checking, etc.), you can just walk the tree and trivially optimize things like that.

      The hard part of optimization comes in when you have to do dynamic analysis of the code to determine whether an optimization changes the meaning of the program. For instance, if you are computing something with the first statement inside the body of the loop, it's possible that the statement can be factored out of the loop since it may not actually depend on anything that changes during the execution of the loop. This may be the case if it, for example, doesn't call any functions or dereference pointers and only refers to variables which are not modified by the loop. However, if it does dereference a pointer and read from that location, then it's probably still OK as long as (a) the loop doesn't write to memory anywhere, and (b) the loop doesn't call any functions that write to memory, and (c) the pointer isn't declared volatile (or cast that way).

      The point here is that compilers can actually handle all the stuff I described about factoring statements out of a loop, and some of them can handle the complex inbetween cases where it's hard to tell if it's safe or not to move that statement. I would not be surprised if some compilers can even analyze the possible values for a pointer and determine whether the pointer could modify something that something else is reading, and make the decision of whether to move the statement outside the loop based on that information.

      Modern compilers are really, really sophisticated. Telling the difference between !ptr and ptr!=NULL is totally cake for them, so I wouldn't worry about it at all.

    31. Re:Huh by SETIGuy · · Score: 1
      If it's standard C, NULL must be zero. There were, in the past, compilers where this was not the case. (Some were compilers for MS-DOS, where offset zero in the data segment might actually be used, and at least one where a zero offset with any segment register value would compare equal to zero. I think older version of VAX C also had a non-zero value for an invalid pointer).

      Of course, now, any platform that uses a non-zero in memory value for a null pointer must hide that fact from the programmer. In other words:

      /* temporarily ignore the nasal demons that this
      * code invokes.
      */

      char *a=NULL;
      /* This assertion must succeed */
      assert(a==0);

      /* ignore invalid assumption that sizeof(unsigned long)==sizeof(char *) */

      /* The following line could do anything, but will do what we want */
      unsigned long c=*(unsigned long *)&a;

      /* This assertion may fail. If it does, it's probably
      * because the memory representation of a NULL pointer is not
      * really zero
      */
      assert(c==0);
    32. Re:Huh by DunbarTheInept · · Score: 1


      there is no way to be entirely certain that the flag values contained in the flag register are consistant with the value of ptr

      Yes there is. The compiler will perform the assignment into ptr as the last step of the malloc line (it has to - the call has to be finished before it assigns its return value into ptr). Therefore the compiler will have the value of ptr in a register already as a side effect of that assignment. All it needs to do is optimize itself to do so using the same register that the JNZ instruction can operate on.


      Compilers now-a-days are awesome tools. Trust them, don't try to out-think them most times.

      Yes. I said so already. You're attempting to belittle me by responding to my post as if I made a point much stupider than the one I actually made. The person I was replying to was claiming that in both cases (!ptr) and (ptr!=NULL), such-and-such, and I was saying in both cases it would be this-and-that. Neither of us was claiming that the two casese would end up being different. Both of us knew the compiler would render them into the same result - we disagreed as to what that result would be.

      --

      Don't label something "offtopic" unless you know the topic well enough to tell what's on topic.

    33. Re:Huh by DunbarTheInept · · Score: 1

      Farking mozilla buggy textarea typing! The jumbled text at the end is NOT what I actually typed. It jumped the cursor about in broken ways as I was typing. (hit backspace, and it goes somewhere totally random within the text instead of to the previous position. I didn't catch that it was doing this until after I posted.)

      --

      Don't label something "offtopic" unless you know the topic well enough to tell what's on topic.

    34. Re:Huh by DunbarTheInept · · Score: 1


      in most C implementations.

      Actually, in ALL C implementations that follow the standard. The standard mandates that NULL be "(void*)0". Only pre-standards versions of K&R old-style C would be allowed to do it differently.

      --

      Don't label something "offtopic" unless you know the topic well enough to tell what's on topic.

    35. Re:Huh by Guy+Harris · · Score: 1
      Actually, in ALL C implementations that follow the standard. The standard mandates that NULL be "(void*)0".

      Yes, but it doesn't mandate that all the bits of the value (void *)0 are zero. In most C implementations they are, but there might be some, or might have been some, where they weren't.

    36. Re:Huh by Anonymous Coward · · Score: 0

      As people said above, the language definition dictates that 0 == NULL. Mod parent idiot.

      That's relatively recent. See here for examples of where that wasn't true

    37. Re:Huh by nothingHappens · · Score: 1

      Odd. In that case, shouldn't the 6502 compiler mentioned have used just BEQ then? IIRC, BEQ acts as "branch if equal to zero" when appears by itself, and "branch if equal" if it appears after a CMP (which essentially just subtracts).

    38. Re:Huh by DunbarTheInept · · Score: 1

      How??

      The only case where a cast can cause bits of value 1 to be added to a value is when the value starts out negative and it's being lengthened to a larger number of bytes (for example, casting (short)-1 into a (long) will pad with 1 bits rather than 0 bits).

      But under what circumstances will a value of zero be padded out with anything other than more zeros when casting it?

      --

      Don't label something "offtopic" unless you know the topic well enough to tell what's on topic.

    39. Re:Huh by Guy+Harris · · Score: 1
      The only case where a cast can cause bits of value 1 to be added to a value is when the value starts out negative and it's being lengthened to a larger number of bytes (for example, casting (short)-1 into a (long) will pad with 1 bits rather than 0 bits).

      You're thinking of a cast of an integral value to a wider integral type.

      That's not what this is - this is converting an integral constant 0 to a null pointer. Such a conversion is not guaranteed to just copy the bits. Nothing in the ANSI C standard says that, for example, on a platform where pointers have a 16-bit segment number and a 32-bit segment offset, and where a null pointer has a segment number of hex FEFE and a segment offset of FFFFFFFF, the expression (void *)0 must result in a pointer with an all-zero segment number and an all-zero segment offset, rather than one with a segment number of FEFE and a segment offset of FFFFFFFF.

      Yes, the note in footnote 45 of page 46 of the ANSI C standard, that "The mapping functions for converting a pointer to an integer or an integer to a pointer are intended to be consistent with the addressing structure of the execution environment." would probably recommend that converting arbitrary integral values (which would have to be 48-bit or longer integral values on this platform) just copy the bits - but that's just a note (the standard just says the mapping is "implementation-defined", and if null pointers have to be FEFE:FFFFFFFF on that platform, then (void *)0 has to map to FEFE:FFFFFFFF even if

      int i = 0;
      char *p = i;

      would result in p being 0000:00000000. Yes, this is a bit counter-intuitive, but, given that C didn't have the notion of "nil" or some other null pointer constant from Day One, that's life.

      See question 5.5 in the comp.lang.c FAQ (and the rest of section 5 of that FAQ, devoted to the null pointer) for more details.

    40. Re:Huh by DunbarTheInept · · Score: 1

      But null pointers are a concept at a higher level than the archetecture. Thus I don't buy the notion that a hardware archetecture would ever mandate that a null pointer must be FEFE:FFFFFFFF. C's Null pointers are a concept at the language level, not the hardware level - some pointer that, despite looking like a valid pointer to the hardware, still is by convention not going to be used for anything 'real'. There's never any reason you'd be unable to use zero for that on some archetecture.

      --

      Don't label something "offtopic" unless you know the topic well enough to tell what's on topic.

    41. Re:Huh by Guy+Harris · · Score: 1
      But null pointers are a concept at a higher level than the archetecture.

      Are you certain of that? Are you certain that no architecture on which C has been implemented has ever mandated a particular null pointer representation? ("Certain" doesn't mean "certain that you have an argument that demonstrates this" - an argument could be making an explicit or implicit assumption that's wrong - "certain" means "certain that there's no architecture in the real world has done that, by looking at those architectures".)

      Null pointers are a concept at the language level, not the hardware level - some pointer that, despite looking like a valid pointer to the hardware, still is by convention not going to be used for anything 'real'.

      There might be hardware on which some bit patterns are defined not to be valid, perhaps even for use as null pointers or other "trap pointers". (Consider, for example, the GE 645 and successors, where one "tag" field in a pointer had a value explicitly intended to cause a trap; Multics used that for run-time dynamic linking, with pointers to functions or data objects in other segments starting out as trap pointers and, in the trap handler, invoking the run-time linker, resolving the reference, and replacing the pointer with a pointer to the object in question. Loading such a pointer caused a trap, so you couldn't copy such a pointer without snapping the link.)

      Consider, also, that C programs don't necessarily exist in a vacuum; C might be implemented on a system with an existing operating system and other languages, in an environment where some not-all-zero value was used for null pointers. It might well be that, for convenience in calling existing non-C APIs, the C null pointer would use the existing null pointer representation. (A shim routine could translate arguments and return values, but might not be able to conveniently translate null pointers in, for example, data structures pointed to by arguments.)

      Perhaps ease of porting existing C code that, for example, assumed that memset( object , 0, sizeof object ) will set all pointer values in object to null pointer values, would be a reason not to do that, but the implementors of C on that platform might still decide, perhaps properly, that ease of interfacing with existing code is more important than ease of porting technically-incorrect C code.

      In practice, you probably will find few platforms on which the representation of null pointers in C does not have all bits zero, but

      1. I wouldn't assume that there aren't any with not all bits zero (and I have the impression that there might have been some where they weren't all zero - I wonder what the null pointer representation is in C in OS/400 on AS/400?);
      2. one cannot find in the ANSI C standard any requirement that null pointers be represented with all their bits zero.
    42. Re:Huh by DunbarTheInept · · Score: 1


      one cannot find in the ANSI C standard any requirement that null pointers be represented with all their bits zero.

      In a single statement? No. In the logical combination of different parts? Probably - but I haven't paid $18.00 plus shipping and handling to get my copy of the actual standard. I only have FAQs and summaries to go on. Here is the logical path (where I outline the specific case where I can't find what the standard says):

      1 - NULL is defined via a cast operation. Since it MUST be a macro of "(void*)0", that means the compiler cannot treat "NULL" and "(void*)0" differently. They must be the same in all cases. Therefore, if there is any mangling of the zero, turning it into something nonzero, it MUST be the cast operator that is doing so, such that if foo=zero, then (void*)foo results in the same mangling of the value as NULL does.

      2 - So long as all the possible values of type Foo are expressable with a mapping into Bar (i.e. Bar is at least as big as Foo), then that means nothing gets lost from a casting of Foo into Bar, or in other words a circular casting chain of: (Foo)(Bar)(Foo)i results in the same 'i' as just (Foo)i does. (***This is what I need to see in the standard to look up - I need to see the section on castings***).

      3 - Therefore, if an implementation maps (int)0 into some nonzero representation for NULL when casting it to (void*), then it must also do the opposite, and cast that same nonzero NULL representation back into zero again when casting from (void*) back to (int).

      4 - boolean expressions automatically get casted back to int.

      5 - therefore the expression:
      if( expr )
      {
      }
      Will result in expr getting silently cast into an int (and if it cannot be cast like that, it's a syntax error, like if expr evaluated to a struct.)
      Therefore the expression:
      if( ! ptr )
      {
      }
      results in a cast from pointer to int, assuming ptr is a pointer.

      Therefore if ptr == NULL, then that casting into an int should reverse the value-mangling that happened when 0 was cast to (void*), and give you back a zero again. If it does not, then it is a broken implementation of the casting operator.

      And if it casts back into an int, and unmangles it back to a zero when doing so, then, to unroll this discussion, a jump-if-zero or jump-if-not-zero could be used by the compiler to implement it.

      In other words, like I said, the concept of an Ansi C NULL pointer is at a higher level than the archetecture, and at that level, NULL is a zero. Thus if the archetecture doesn't like calling it zero, then the compiler will have to do some "magic" to make it present the lie that its a zero to the programmer.

      --

      Don't label something "offtopic" unless you know the topic well enough to tell what's on topic.

    43. Re:Huh by Guy+Harris · · Score: 1

      In a single statement? No. In the logical combination of different parts? Probably - but I haven't paid $18.00 plus shipping and handling to get my copy of the actual standard. I only have FAQs and summaries to go on.

      Well, I have ANSI C89 - at some point I may pay CHF 340 or so for ISO C99. I did find a C99 draft from January 18, 1999, but they might have changed the stuff about null pointers since then. However, given that they probably didn't intend to break valid C89 code if they didn't have to, I suspect they didn't change too much.

      - NULL is defined via a cast operation. Since it MUST be a macro of "(void*)0",

      That's presumably a C99ism - C89 makes no such requirement.

      that means the compiler cannot treat "NULL" and "(void*)0" differently. They must be the same in all cases. Therefore, if there is any mangling of the zero, turning it into something nonzero, it MUST be the cast operator that is doing so, such that if foo=zero, then (void*)foo results in the same mangling of the value as NULL does.

      Where in the C99 standard does it say that casting an integral constant 0 to void * must yield the same result as casting an integer variable with the value 0 to void *. It might be "obvious" that they must yield the same result, but "obvious" and "true" aren't always the same thing. Section 3.3.2.3 in C89 speaks of an integral constant expression 0, or such a constant cast to void *, as being a "null pointer constant", and speaks of a "null pointer constant", converted to a pointer when assigned to or compared with another pointer, as being a "null pointer". The Rationale says

      Since pointers and integers are now considered incommensurate, the only integer that can safely be converted to a pointer is the constant 0. The result of converting any other integer to a pointer is machine dependent.

      They don't explicitly say that the result of converting non-constant value that happens to be zero to a pointer is not necessarily the same as the result of converting a constant 0 to a pointer, but the fact that they explicitly say "the constant 0" rather than "0" suggests that they were at least thinking in those terms.

      2 - So long as all the possible values of type Foo are expressable with a mapping into Bar (i.e. Bar is at least as big as Foo), then that means nothing gets lost from a casting of Foo into Bar, or in other words a circular casting chain of: (Foo)(Bar)(Foo)i results in the same 'i' as just (Foo)i does. (***This is what I need to see in the standard to look up - I need to see the section on castings***).

      Please do look it up - and make sure it applies to mappings beetween integers and pointers. Please also note that casts are not the only places where conversions take place; there are places where a conversion is performed without a cast, e.g. an assignment where the LHS and RHS have different types, including, at least in C89, an assignment of a null pointer constant to a pointer, such as char *p = 0.

      4 - boolean expressions automatically get casted back to int.

      If true, that must be a C99ism, given that there's no such thing as a Boolean type in C89.

      5 - therefore the expression: if( expr )

      {
      }
      Will result in expr getting silently cast into an int

      I doubt that; I rather suspect that either C99 doesn't consider expr to be Boolean in that context if it lacks a comparison operator, or Boolean expressions don't get converted to int, because if expr is an expression of pointer or floating-point type, converting it to an int can lose information (consider a system with 64-bit pointers and 32-bit ints).

      What C89 says about an expression in an if is implicitly comp

    44. Re:Huh by DunbarTheInept · · Score: 1

      A couple of points:

      1 - You are using the term "conversion" as being something different than what I was calling "implicit casting". Your example of LHS and RHS types differing is exactly what my term "implicit casting" was referring to. Consider the following two statements:
      long foo = 1L;
      int bar = 2; ... // Two similar statements:
      foo = bar; // 1
      foo = (long)bar; // 2

      If version 1 does something different from version 2, then your compiler is broken.

      2 - As to your comment "given that there's no such thing as a Boolean type in C89" - I never said Boolean type. I said Boolean expression: For example "x y", or " !ptr "

      3 - There are a few things the standard doesn't explicitly say that still makes an implementation be broken if it doesn't do it. For example, there's no guarantee that malloc() ever return anything other than NULL. Theoretically a C library could put in a stub that just says "return NULL" for malloc(), and be following the standard library rules, and yet it would still be broken and completely useless. Similarly, regardless of what the standard says, any compiler that treats a casting of a literal constant differently than the casting of a variable with the same value as that constant, is inherently broken. Any compiler that mangles a value when converting one-way and doesn't inverse the mangling as best it can when going the other, is also inherently broken. The only excuse for that is if the values are literally impossible to convert without lossage - like trying to take a value of 800 billion in a long, and stuff it into a short. Clearly that is not the case with the NULL pointer mapping.

      So I will concede the point, with that caveat. It is possible to make a broken piece of shit compiler that technically conforms to the standard in the letter of the law but not the spirit of the law, and does what you say. It would not really be "C", though, in the same sense that Microsoft's "Posix" isn't really Posix despite hitting all the bullet points in the listed rules.

      The blame for that lays partly with the compilers and partly with the standards committe for not nailing things down. There are too many places where something is left "implementation dependant" even though there is one way to do it that makes the most obvious logical sense to a programmer trying to use the language - like casting being two-way wherever possible, and implicit versus explicit casting having the same effect everywhere, and casting a constant having the same effect as casting a variable of the same type.

      --

      Don't label something "offtopic" unless you know the topic well enough to tell what's on topic.

    45. Re:Huh by DunbarTheInept · · Score: 1


      For example "x y", or " !ptr "

      (correction, that should be "x < y" or " !ptr " -- HTML ate my less-than)

      --

      Don't label something "offtopic" unless you know the topic well enough to tell what's on topic.

    46. Re:Huh by Krach42 · · Score: 1

      /me pulls up his trusty x86 architecture reference

      Hm... hm... HMM...... yep... movl doesn't change any flags at all.

      There is literally no way to guarantee the output of a set of flags on the x86 architecture. Now, DOS, and the BIOS use numerous calls that do return values in the flags, but those are defined flag values same as a return value. The C library must convert these flag values into value passed through EAX, such that the C programmer can actually deal with them.

      So, again. The MOVL instruction involving putting the ptr value into EAX does not affect flags at all. (On the HC11 it does, but the Z80 doesn't. By and in large most architectures do not update flags on a simple move to register instruction)

      So, let's look at a malloc() wrapper, that qualifies in all ways the necessary criteria to be a proper malloc, but would kill all flag results.

      _malloc:
      call _the_real_malloc
      orl %edx, %edx
      ret

      Wow, look at that. It just calls the real malloc, and then kills all the flags. Now, in regards to C/C++, we don't care as flags and condition codes are not visible to the programmer. So, this function has 0 effect on all C code generated complying with standards. Now, let's take a look at the code that YOU'RE saying it should generate.

      call _malloc
      jnz _skip
      call _barf
      ret
      _skip:

      This code would *fail*. And because of that, it is an invalid compilation of ptr = malloc() if(!ptr).

      Do not assume because I'm belittling you, that I didn't understand what you were trying to say, or imply. I understood exactly what you meant. And you're wrong, and anyone who understands computer architectures can see why. My post is an attempt to enlighten you as to why your code, that you're so confident would work, wouldn't.

      --

      I am unamerican, and proud of it!
  26. compilers are 'smart', but... by LegendOfLink · · Score: 1

    It's always a good idea to practice good coding. This way you'll not only depend on the compiler to do all the coding, but you'll also remain Sup3R l33t.

  27. $.02 by MagicM · · Score: 4, Insightful

    1) Code for maintainability
    2) Profile your code
    3) Optimize the bottlenecks

    That said, (!ptr) should be just as maintanable as (ptr == NULL) simply because it is a frequently used 'dialect'. As long as these 'shortcuts' are used throughout the entire codebase they should be familiar enough that they don't get in the way of maintainability.

    1. Re:$.02 by arkanes · · Score: 1

      The !ptr form is actually more likely to be a performance problem in higher level/interperted languages, strangely enough, where it forces a type coercion to boolean rather than an integer compare.

    2. Re:$.02 by Felonious+Monk · · Score: 1

      That all there is to it. It's just that far to many programmers omit the "Profile your code" step.

    3. Re:$.02 by Anonymous Coward · · Score: 0

      stick with the (!ptr) construct to avoid 'if (ptr = NULL)'

    4. Re:$.02 by DarthVain · · Score: 1

      1)Optimize your code
      2)???
      3)PROFIT!

      OK that doesn't even make sense... but someone was going to do it.

    5. Re:$.02 by mkosmul · · Score: 1

      For precision's sake: you probably wanted to say it's an 'idiom', not a 'dialect'. C99 (or any other variant of the language) is what you call a dialect.

    6. Re:$.02 by MagicM · · Score: 1

      Yes, you're right. I wanted to say "idiom".

      Damnit, why didn't I say "idiom"?! My one chance in life to use the word "idiom" and I blew it!

      LAUNCELOT: No, no, sweet Concorde! Stay here! I will send help as soon as I have accomplished a daring and heroic rescue in my own particular...
      *sigh*

      CONCORDE: Idiom, sir?

    7. Re:$.02 by Guy+Harris · · Score: 1
      The !ptr form is actually more likely to be a performance problem in higher level/interperted languages, strangely enough, where it forces a type coercion to boolean rather than an integer compare.

      Presumably by "higher level languages" you mean "languages that have a Boolean type and where ! takes a Boolean argument"; C is not one of those languages.

      ("Interpreted" isn't needed or wanted in that statement, so I removed it; one could have an interpreted implementation of C - and, in fact, Googling for "c interpreter" finds some, although I didn't check whether any that didn't explicitly say they weren't complete ANSI C implementations were - and one could have a language with a Boolean type and a ! operator that requires a Boolean argument and that has a non-interpreted implementation.)

  28. Tight complex recursive loops by LiquidCoooled · · Score: 2, Interesting

    An example would be searching and sorting algorythms (I know there have been thousands of variations, and entire libraries now exist, but theres always some other need for a non generic search function)

    I could write sloppy code which appears to be significant, but then realise that holding this here, and keeping that register there, then I can do such a thing just a fraction quicker than before.

    Its not so much going to the assembler level anymore, but a tightly coded loop tuned by human intuition will almost always still be faster than anything an optimiser can give.

    I recently had an issue with sorting collections containing thousands of none trivial objects. Every time I adjusted the adready fast quicksort, I gained a little more speed.

    Its always been the way, and until genetic compilation and optimisation comes along trying every combination, it will continue to be the case.

    --
    liqbase :: faster than paper
    1. Re:Tight complex recursive loops by Anonymous Coward · · Score: 1, Interesting
      Parent wrote:

      Every time I adjusted the adready fast quicksort, I gained a little more speed.

      Beware of trying to "tune" quicksort. The stock quicksort that comes with your stdlib is already tuned for maximum *average* performance.

      Keep in mind that quicksort will always have a worst case performance of O(n^2); however, on average it runs about 10% faster than the fastest possible heapsort and mergesort algorithms, which are both O(log n). The main reason for using quicksort is the fact that it's 10% faster *on average* than the pure O(log n) algorithms.

      Any 'optimizations' you make to quicksort may boost performance for degenerate data sets that hit the 'worst case' on several recursions of quicksort, but they might hurt average performance. If you end up doing more than 10% damage to the average, then you might as well be using a strictly O(log n).

      If you're not willing to get your modifications to quicksort peer reviewed, don't bother touching it.

      -my 2 cents

    2. Re:Tight complex recursive loops by LiquidCoooled · · Score: 1

      my modifications weren't to the algorythm itself, more to the specific implimentation.
      Sorting an array of integers is one thing, handling lookups and retaining the calculated current pivot weight nearby are where my tuning was aimed. It turned a sluggish routine into something quick and responsive.
      Your spot on about the average, and quite rightly suggest the right tool for the job in certain situations :)
      Theres no need for peer review, the coding is done, it operates to my expectations of speed, and the customer is satisfied :)

      --
      liqbase :: faster than paper
  29. micro optimization by fred+fleenblat · · Score: 4, Insightful

    What you're talking about it micro-optimization.
    Compilers are pretty good at that, and you should let them do their job.

    Programmers should optimize at a higher level: by their choice of algorithms, organizing the program so that memory access is cache-friendly, making sure various objects don't get destroyed and re-created unnecessarily, that sort of thing.

  30. Wrong, wrong, wrong by JoeBuck · · Score: 4, Informative
    Don't give advice when you don't know C. C requires that when a 0 is converted to a pointer, the result is NULL, so it is absolutely false to claim that NULL could be defined as -1.

    "ptr == 0" must give the same result as "ptr == NULL", always.

    1. Re:Wrong, wrong, wrong by Anonymous Coward · · Score: 0

      but !ptr is clearer and easier to read.

    2. Re:Wrong, wrong, wrong by Anonymous Coward · · Score: 0

      That wouldn't be C. Changing the value of NULL is a hypothetical change to the *language*, not to the "underlying platform".

    3. Re:Wrong, wrong, wrong by Anonymous Coward · · Score: 4, Informative

      From the ANSI C specification, section 6.2.2.3:

      An integral constant expression with the value 0, or such an expression cast to TypeIs_VoidPointer, is called a null pointer constant. If a null pointer constant is assigned to or compared for equality to a pointer, the constant is converted to a pointer of that type. Such a pointer, called a null pointer, is guaranteed to compare unequal to a pointer to any object or function. A null pointer constant has TypeIs_NULL.

      Once again, it should be said:

      Don't give advice not to give advice to not give advice when you don't know C when you don't know C when you don't know C.

    4. Re:Wrong, wrong, wrong by Anonymous Coward · · Score: 1, Informative

      Actually, it doesn't. ANSI C, at least, does not define NULL - that is system-dependent. There may not be any systems that choose to use anything except 0, but this is not standardized at all (unless C99 covers it).

    5. Re:Wrong, wrong, wrong by /Wegge · · Score: 1

      Althoug the comparision (0 == ptr) might for some twisted reason com out as a non-zero value, you are not guaranteed that (!ptr) will have the same value. In other words, the C standard does not guarantee that (0 == 0) yields the same result as (!0), (0 == NULL) or (!NULL).

      To repeat the cascade:

      Don't give advice not to give advice not to give advice to not give advice when you don't know C when you don't know C when you don't know C when you don't know C.

      --
      //Wegge
    6. Re:Wrong, wrong, wrong by Anonymous Coward · · Score: 0

      You're pretty much entirely wrong.

      NULL is implementation defined, yes. But the implementation must choose for it to be a null pointer constant. It can't just choose any random value, it must choose a null pointer constant.

      This restriction greatly limits the range of values which can be chosen to 0 and ((void*)0), or some similar value like 0L.

      The "implementation defined" part just allows it to choose between 0 or ((void*)0). Yes, this applies to C89 and C99.

    7. Re:Wrong, wrong, wrong by DunbarTheInept · · Score: 1

      The ISO standard says that an implementation is NOT free to do that.
      Maybe in the days of K&R that was true.

      --

      Don't label something "offtopic" unless you know the topic well enough to tell what's on topic.

    8. Re:Wrong, wrong, wrong by Anonymous Coward · · Score: 0

      What if you are comparing a boolean to a instr() type function that can return a valid 0?

      Even if you understand how the language works, it's good practice to use styles that avoid possible bugs, such as triple equals.

    9. Re:Wrong, wrong, wrong by lederhosen · · Score: 1

      You could define NULL to be 0xFFFFFFFF (i.e. -1), a pointer with that value must still equal 0.

      void* x = 0xFFFFFFFF;
      if (x == 0)
      printf("0xFFFFFFFF == 0");

      could print "0xFFFFFFFF == 0" on some strange architecture, and I have read that there exist
      som odd architecture that uses a binary value
      that is _not_ equal to all zeroes.

    10. Re:Wrong, wrong, wrong by lederhosen · · Score: 1

      Question 5.5

      How should NULL be defined on a machine which uses a nonzero bit pattern as the internal representation of a null pointer?

      The same as on any other machine: as 0 (or ((void *)0)).

      Whenever a programmer requests a null pointer, either by writing ``0'' or ``NULL,'' it is the compiler's responsibility to generate whatever bit pattern the machine uses for that null pointer. Therefore, #defining NULL as 0 on a machine for which internal null pointers are nonzero is as valid as on any other: the compiler must always be able to generate the machine's correct null pointers in response to unadorned 0's seen in pointer contexts. See also questions 5.2, 5.10, and 5.17.

      References: ANSI Sec. 4.1.5
      ISO Sec. 7.1.6
      Rationale Sec. 4.1.5

      (http://www.eskimo.com/~scs/C-faq/q5.5.html)

    11. Re:Wrong, wrong, wrong by swillden · · Score: 3, Informative

      Althoug the comparision (0 == ptr) might for some twisted reason com out as a non-zero value, you are not guaranteed that (!ptr) will have the same value.

      Wrong

      Don't give advice... ah, screw it. You get the idea.

      --
      Note to ACs: I usually delete AC replies without reading them. If you want to talk to me, log in.
    12. Re:Wrong, wrong, wrong by PoopJuggler · · Score: 3, Interesting

      Any company who makes a C compiler where NULL != 0 will not get much business methinks

    13. Re:Wrong, wrong, wrong by Anonymous Coward · · Score: 0

      If there any 32-bit architectures out there that use 1's complement arithmetic then:

      0xFFFFFFFF is a minus 0.

    14. Re:Wrong, wrong, wrong by Anonymous Coward · · Score: 0

      Better to habitually write such expressions it the reversed operand form "if(NULL==ptr)" since the compiler will flag the common typographic mistake of "if(NULL=ptr)" with an invalid Lvalue error, rather than leave it as a runtime detectable bug.

    15. Re:Wrong, wrong, wrong by Anonymous Coward · · Score: 0

      I'm not sure if you know the language as well as you think. If I am not mistaken NULL is not part of the C language, but it is part of the standard library. In fact in the C reference manual it says, "The value of the macro NULL is the traditional null pointer constant. Many implementations define it to be simply the integer constant 0. In ISO C the macro is defined in many header files for convenience"

      If it was part of the language it would not be a macro. For example in Java it is part of the language.

      Having uninitialized pointers being set to 0 is a standard but is not enforced inside the language. So you could run into some strange architecture where for what ever reason 0xDEADBEEF is the standard. Having it defined to be zero would go against the general idea of C being as architecture independent as possible.

    16. Re:Wrong, wrong, wrong by arcanumas · · Score: 1
      Any company who makes a C compiler where NULL != 0 will not get much business methinks

      But they can certainly profit from selling support :)

      --
      Slashdot Sig. version 0.1alpha. Use at your own risk.
    17. Re:Wrong, wrong, wrong by Anonymous Coward · · Score: 0
      Don't give advice when you don't know C. C requires that when a 0 is converted to a pointer, the result is NULL, so it is absolutely false to claim that NULL could be defined as -1.
      It must be nice to live in a world of highly-regular architectures and strictly-standards-compliant compilers. Mind if I visit?
    18. Re:Wrong, wrong, wrong by Anonymous Coward · · Score: 0

      You can optimize the "Don't give advice..." to STFU

    19. Re:Wrong, wrong, wrong by wiredlogic · · Score: 2, Interesting

      No, "implementation defined" means that it is up to the compiler, OS (if present), and possibly the hardware to determine what will be used to represent the NULL address.

      This is addressed in the C-FAQ where systems from Prime, Data General, and Honeywell-Bull are noted for having non-zero null pointers (at least for their C-compilers).

      This issue brings up one of my pet peeves with C++. The designers (I don't think Stroustroup deserves all the blame)went all out in adding weak type safety to the language by eliminating automatic casts but then they determined that "((void)(*0))" violated they safety model and decided to invoke special "spooky" behavior when comparing pointers against the literal zero. This of course leads to the annoying practice of leaving out the Boolean operator altogether and using "if(foo)" and "if(!foo)".

      I imagine the C++ architects were at least partially motivated by their "macros are evil" mantra (why they didn't do anything about the need for header guard macros is beyond me). They should have had the guts to introduce a new "null" keyword. This would not conflict with existing ANSI C code using NULL and code could easily be ported with substitution or:

      #define NULL null
      I can't believe that this wasn't proposed at some time. It must have been shot down because someone complained that it would break their legacy C code. Only a fool would put case variants of standard macros and keywords into their C code and porting older pre-standard-NULL K&R code would require revisions anyway. They deserve any breakage if they tried to port such crap to C++.
      --
      I am becoming gerund, destroyer of verbs.
    20. Re:Wrong, wrong, wrong by mparker762 · · Score: 1

      The lisp machines had (have, for those of us that still own one) this property.

    21. Re:Wrong, wrong, wrong by Anonymous Coward · · Score: 1, Informative

      AFAIK:

      NULL equals (void*)0

      Yet...

      (void*)0 may or may not have the same bitpattern as (int)0 due to implementation... stuff.

      The standard does make one thing clear:
      If null pointers are not represented as the value 0 then they must be explicitly converted to 0 when converting the null pointer to an integer.

      In general, anything converted to (void*) and back again shall retain it's original value.

      HOWEVER, I can't find where the standard enforces the idea that the size of a pointer type must be of less than or equal to int or long. Yet, when pointer type is converted to an arithmetic type it is treated as an unsigned integer. Thus, the ability to convert pointer types to long - without losing information - is implementation dependent. Hence, the standard allows that object and function pointers could have different representations. If arithmetic and pointer types have different representations then some sort of conversion is done, and it is up to the programmer to understand what is going on.

    22. Re:Wrong, wrong, wrong by Anonymous Coward · · Score: 0

      (void*)0 may or may not have the same bitpattern as (int)0 due to implementation... stuff.

      Which is all I was saying. Thanks for the Score -1,Troll mod, guys.

    23. Re:Wrong, wrong, wrong by Anonymous Coward · · Score: 0

      No, "implementation defined" means that it is up to the compiler, OS (if present), and possibly the hardware to determine what will be used to represent the NULL address.

      Close enough on the definition of "implementation defined", however the language spec still requires NULL to be defined as a null pointer constant, which basically means a constant expression that evaluates to 0, optionally cast to void*. Read the standard, or even a good C book.

      Bottom line is that 1) the macro NULL *MUST* be equivalent to 0, 2) a constant expression that evaluates to 0 *MUST* be interpretted by the compiler as a null pointer if it appears in a pointer context, and 3) the compiler is under no obligation to use "all-bits-zero" internally to represent a null pointer -- but it is required to translate constant expressions that evaluate to 0 into its internal representation for null if they appear in a pointer context.

      This issue brings up one of my pet peeves with C++. The designers (I don't think Stroustroup deserves all the blame)went all out in adding weak type safety to the language by eliminating automatic casts but then they determined that "((void)(*0))" violated they safety model and decided to invoke special "spooky" behavior when comparing pointers against the literal zero.

      For one thing, ((void)(*0)) violates the language syntax, not the safety model. For another, pointer comparisons to literal zeros are exactly the same in C++ as in C. There is nothing "spooky" about it -- at least, no moreso than in C.

    24. Re:Wrong, wrong, wrong by Anonymous Coward · · Score: 0

      If there any 32-bit architectures out there that use 1's complement arithmetic then:

      0xFFFFFFFF is a minus 0.


      Which is entirely irrelevant to the question at hand. The machine's internal representation doesn't matter at all. The C Standard dictates how NULL can and cannot be defined. It just so happens that it MUST be 0 (or something equivalent, optionally cast to void*). This does NOT, however, mean that the all-bits-zero representation must be used internally for a null pointer. The compiler must simply recognize a 0 in a pointer context in the source and translate it as appropriate.

    25. Re:Wrong, wrong, wrong by Anonymous Coward · · Score: 0
      C requires that when a 0 is converted to a pointer, the result is NULL, so it is absolutely false to claim that NULL could be defined as -1.

      You're close but you're still wrong!

      The fact is that "the symbolic constant NULL is often used in place of zero" and "the constant zero may be assigned to a pointer" (both of these quotes are from the 2nd ed. K&R, p. 102). This means that the constant zero may be used in operations (such as assignment and comparison). NULL is simply a #define for zero. Note that this does not say that you can use non-constant zero to compare to a pointer. So according to this language, it may or may not be legal to do, say int x = foo(); if (ptr == x-x) { whatever(); }.

      Also note that I am being nitpicky, and it is true as you said that comparing a pointer with NULL and comparing it with constant zero are both defined to do the exact same thing.

    26. Re:Wrong, wrong, wrong by Anonymous Coward · · Score: 0

      This of course leads to the annoying practice of leaving out the Boolean operator altogether and using "if(foo)" and "if(!foo)".

      Meh, I think it's perfectly clear. "if (foo)" == "if foo points to something." "if (!foo)" == "if foo does not point to anything."

      They should have had the guts to introduce a new "null" keyword.

      I believe they're considering adding "nullptr" to the next revision.

    27. Re:Wrong, wrong, wrong by Anonymous Coward · · Score: 0

      Not if you #define NULL (-1) ... (in which case you deserve what you get).

  31. Compiler Optimization by sameerdesai · · Score: 1

    Isn't this a huge research topic in itself. And I am confident that we will get better compiler optimizations as we go forward. This makes us come to next question about code complexity. I always believe simpler code would also help compiler to help optimize code better apart from user readability. At this same time when we talk about compiler optimizations it is useful to understand the underlying hardware which has capacity to increase the Instruction level parellelism (ILP) and introduce its own optimization using pipelining.

  32. .NET Has An *Easy* Way for Compiler Optimization by PepeGSay · · Score: 1

    Take the two sample ways to implement and then compile them. Then look at the MSIL that is created, if they are the same, then they were optimized to be identical. This works for most simple constructs, such as the one in the message body. If they are different then you have to know the relative costs of what the MSIL is doing in order to figure it out.

  33. Those who forget Tony Hoare... by smug_lisp_weenie · · Score: 5, Insightful

    ...are doomed to repeat the biggest trap in computer programming over and over again:

    "Premature optimization is the root of all evil"

    If there's only one rule in computer programming a person ever learns, "Hoare's dictum" is the one I would choose.

    Almost all modern languages have extensive libraries available to handle common programming tasks and can handle the vast majority of optimizations you speak of automatically. This means that 99.99% of the time you shouldn't be thinking about optimizations at all. Unless you're John Carmack or you're writing a new compiler from scratch (and perhaps you are) or involved in a handful of other activities you're making a big big mistake if your spending any time worrying about these things. There are far more important things to worry about, such as writing code that can be understood by others, can easily be units tested, etc.

    A few years ago I used to write C/C++/asm code extensively and used to be obsessed with performance and optimization. Then, one day, I had an epiphany and started writing code that is about 10 times slower than my old code (different in computer language and style) and infinitely easier to understand and expand. The only time I optimize now is at the very very end of development when I have solid profiler results from the final product that show noticable delays for the end user and this only happens rarely.

    Of course, this is just my own personal experience and others may see things differently.

    1. Re:Those who forget Tony Hoare... by taybin · · Score: 1

      I think Donald Knuth is the original source of that quote.

    2. Re:Those who forget Tony Hoare... by smug_lisp_weenie · · Score: 1

      There is a long debate about who said it first. Read here

    3. Re:Those who forget Tony Hoare... by RNLockwood · · Score: 1

      "Premature optimization is the root of all evil"

      Not if the opinion of the two women at the table next to me at luch last week is correct!

      --
      Nate
    4. Re:Those who forget Tony Hoare... by neonstz · · Score: 3, Insightful
      A few years ago I used to write C/C++/asm code extensively and used to be obsessed with performance and optimization. Then, one day, I had an epiphany and started writing code that is about 10 times slower than my old code (different in computer language and style) and infinitely easier to understand and expand. The only time I optimize now is at the very very end of development when I have solid profiler results from the final product that show noticable delays for the end user and this only happens rarely.

      It is important to be aware of that here are different types of optimizing. Optimizing code where the compiler probably does a good job is just stupid unless the code turns out to be a major bottleneck.

      However, not thinking about optimization/speed early can IMHO be very dangerous. If the project is a bit large and complex, a nice design on the whiteboard may very well turn up to be dead slow with no chance in hell to make it run significantly faster without redesigning/rewriting the entire thing (this doesn't really have anything to do with compiler optimization though).

      I've been working in a project (I wasn't in it in the beginning), where the design probably looked good for some people in the design document (although I don't really agree on that neither), but the performance aspect was neglected until the application turned out to be quite slow. Adding mechanisms to make it run faster has been quite "challenging". (My personal opinion in this piece of software is that performace issues was ignored even from early design because the wrong people making the decisions. Basically they didn't focus on where performance really was needed.

      So after a few years my experience bottles down to: "If you have a performace requirement, make sure your code keeps up the entire time." and "You can't get both high performance and general purpose stuff in the same piece of code".

    5. Re:Those who forget Tony Hoare... by Anonymous Coward · · Score: 0

      Let me guess, you started writing in Visual Basic?

    6. Re:Those who forget Tony Hoare... by smug_lisp_weenie · · Score: 1

      You make many good points here and I agree with what you say mostly...my post was somewhat simplified for the sake of conciseness...

      Clearly, I made some assumptions in my initial post: The most important being that given moore's law, most "function calls" in a typical application now are well below 1 miliseconds per call. My argument is that, with such speedy functions, you can afford a lot of performance loss in the name of cleaner code in most cases- And if not, chances are a library already exists to do the "dirty work" in the few cases where hard optimization is needed.

      There are some types of "function calls" that are greater than 1ms: These include functions that perform web queries or database queries: In these cases (and I suspect your anecdote most likely involves one or the other) clearly performance can become a problem with a poor design. However, the interest of clean code and good performance are usually not a conflicting in this case as people often make out (IMHO): The key is to use caching on the client to improve performance, which also has great code benefits (it allows the technical and logical aspects of the query to be decoupled) and a clean code design usually still is quite compatible with good performance.

      Although I am probably a bit out on a limb here, I would argue that the kinds of problems you describe in your case study were possibly due to not taking the whole process of "clean code over optimization" far enough and instead the designers created an ugly hybrid of performance/elegance that took short cuts that were the primary culprit. Just my thoughts on the matter...

    7. Re:Those who forget Tony Hoare... by smug_lisp_weenie · · Score: 1
    8. Re:Those who forget Tony Hoare... by tepples · · Score: 1

      given moore's law, most "function calls" in a typical application now are well below 1 miliseconds per call.

      Given Moore's law, more transistors per cm^2 will draw more current. Battery capacity has not nearly kept up with Moore's law. In addition, when you have to get everything done in 16 milliseconds (the time between vblanks), 1 millisecond seems like an eternity.

      The key is to use caching on the client to improve performance

      Not always. If you overcache, you may reveal things to the user that you don't want to reveal to the user. Overcaching is why wallhacks work.

    9. Re:Those who forget Tony Hoare... by smug_lisp_weenie · · Score: 1

      Well, if you're programming for a GBA, my rule of thumb breaks down a bit. Moore's law and high-level graphics libraries just aren't helpful enough (yet) on such a platform. (on a PC, I would say you should just have John Carmack/etc worry about vsyncs and buy his library)

      As for the "wallhacks" comment, that's an interesting point that complicates the discussion quite a bit... I might have a comment on that after some thought :)

    10. Re:Those who forget Tony Hoare... by ashultz · · Score: 1

      Well, eventually everyone will have the same personal experience and come around to your side. No need to work too hard in optimizing their attitudes prematurely... eventually you can just profile them and see who the holdouts are, and take away their keyboards.

    11. Re:Those who forget Tony Hoare... by adrianbaugh · · Score: 1

      > Then, one day, I had an epiphany and started writing code that is about 10 times slower than my old code

      Did you get a job at Microsoft, then?

      --
      "'I pass the test,' she said. 'I will diminish, and go into the West, and remain Galadriel.'"
      - JRR Tolkien.
    12. Re:Those who forget Tony Hoare... by Bill+Dog · · Score: 1

      There's no need for you and your partner to suffer in silence due to the stigma surrounding premature optimization, and other forms of programming dysfunction. Treatment is just a phone call away! ;-)

      --
      Attention zealots and haters: 00100 00100
  34. "time" is your friend by Anonymous Coward · · Score: 0

    TIME(1) TIME(1)

    NAME
    time - time a simple command or give resource usage

    SYNOPSIS
    time [options] command [arguments...]

    DESCRIPTION
    The time command runs the specified program command with the given
    arguments. When command finishes, time writes a message to standard
    output giving timing statistics about this program run. These statis-
    tics consist of (i) the elapsed real time between invocation and termi-
    nation, (ii) the user CPU time (the sum of the tms_utime and tms_cutime
    values in a struct tms as returned by times(2)), and (iii) the system
    CPU time (the sum of the tms_stime and tms_cstime values in a struct
    tms as returned by times(2)).

  35. Write C for C programmers by swillden · · Score: 5, Insightful

    With regard to your example, I can't imagine any modern compiler wouldn't treat the two as equivalent.

    However, in your example, I actually prefer "if (!ptr)" to "if (ptr == NULL)", for two reasons. First the latter is more error-prone, because you can accidentally end up with "if (ptr = NULL)". One common solution to avoid that problem is to write "if (NULL == ptr)", but that just doesn't read well to me. Another is to turn on warnings, and let your compiler point out code like that -- but that assumes a decent compiler.

    The second, and more important, reason is that to anyone who's been writing C for a while, the compact representation is actually clearer because it's an instantly-recognizable idiom. To me, parsing the "ptr == NULL" format requires a few microseconds of thought to figure out what you're doing. "!ptr" requires none. There are a number of common idioms in C that are strange-looking at first, but soon become just another part of your programming vocabulary. IMO, if you're writing code in a given language, you should write it in the style that is most comfortable to other programmers in that language. I think proper use of idiomatic expressions *enhances* maintainability. Don't try to write Pascal in C, or Java in C++, or COBOL in, well, anything, but that's a separate issue :-)

    Oh, and my answer to your more general question about whether or not you should try to write code that is easy for the compiler... no. Don't do that. Write code that is clear and readable to programmers and let the compiler do what it does. If profiling shows that a particular piece of code is too slow, then figure out how to optimize it, whether by tailoring the code, dropping down to assembler, or whatever. But not before.

    --
    Note to ACs: I usually delete AC replies without reading them. If you want to talk to me, log in.
    1. Re:Write C for C programmers by Anonymous Coward · · Score: 2, Funny

      And write C++ for C++ programmers:

      try
      {
      if (1 / (int)ptr)
      ;
      cout << "ptr is not null";
      }
      catch (...)
      {
      cout << "ptr is null";
      }

    2. Re:Write C for C programmers by 14erCleaner · · Score: 3, Interesting
      I disagree with you about the readability of (!ptr), but at least it is a very common idiom in C, and I can accept that.

      But please, oh, please, don't write this:

      if (!strcmp(x,y))

      Intuitively, that looks exactly backwards from what it's testing (equality).

      On the "optimize for the compiler" issue, I think what's been said already is right: don't do it unless it's in a critical spot, write code for readability (and big-picture efficiency) first, then worry about local optimizations only if there's a problem.

      --
      Have you read my blog lately?
    3. Re:Write C for C programmers by Lord+Crc · · Score: 1
      I actually prefer "if (!ptr)" to "if (ptr == NULL)", for two reasons

      Thats one of the things I've yet to grasp when it comes to C. In Delphi we have a function called Assigned() which, you might have guessed it, returns true if the pointer is not NULL (or nil in pascal), false otherwise. Why isn't such a macro baked into the some common framework, or why doesn't more people use such a macro?
      if (assigned(p))
      foo(p);
      seems pretty clear to me.
    4. Re:Write C for C programmers by John+Bokma · · Score: 1

      "parsing the "ptr == NULL" format requires a few microseconds of thought to figure out what you're doing. "!ptr" requires none." Only if it's your own code. The former stands more out than the latter, it's easy to skip over the !, and read the entire if wrong. If you notice this, you skip back to the if and then see the !. I love Perl's unless: unless ( ptr ) { } ... that reads way more easier compared to both forms IMNSHO.

    5. Re:Write C for C programmers by Anonymous Coward · · Score: 0
      14erCleaner wrote:

      But please, oh, please, don't write this:

      if (!strcmp(x,y))

      Intuitively, that looks exactly backwards from what it's testing (equality).

      I'm not particularly advocating that as the prefered way to write that test, but intuitively it doesn't look like anything at all. The intuitive reading of that is "if strings x and y don't compare"... Huh? What the heck is that supposed to mean? What would it mean if they did "compare"? There is no way "x and y compare" intuitively means "x and y are equal".
    6. Re:Write C for C programmers by Anonymous Coward · · Score: 0

      > I actually prefer "if (!ptr)" to "if (ptr == NULL)",
      > for two reasons.
      > [...]
      > The second, and more important, reason is that to anyone
      > who's been writing C for a while, the compact representation
      > is actually clearer because it's an instantly-recognizable idiom

      That only works if all you ever do is program C, you have done so for at least 2 years, and you have 20/20 eyesight.

      I find that I need to set the font to 'too large' to easily see the difference between if(ptr) and if(!ptr).

    7. Re:Write C for C programmers by Anonymous Coward · · Score: 0

      I have written a lot of code both ways, and am comfortable with either. Lately, though, I have come around to the "if (NULL == ptr)" form, because strictly speaking ptr is not a boolean type -- even though, of course it evaluates to zero or non-zero.

      As for optimization, as many others have already pointed out, 99.99% of todays compilers will generate the same code in both cases, and a programmer's time is better spent developing an efficient (and correct!) algorithm.

    8. Re:Write C for C programmers by IvyMike · · Score: 1

      One common solution to avoid that problem is to write "if (NULL == ptr)", but that just doesn't read well to me.

      I've seen people recommend that idiom, which can also be used for any comparison against a constant, such as "if (5 == varx)". I agree that it doesn't read well to me, but I have another reason I don't like it.

      This may be belaboring the point, but the argument for the construct is that you type "if (5 = varx)", the code won't compile, and you'll catch your mistake.

      But I'm not sure how much this actually helps, because it may ultimately reduce your vigilance about "=" vs. "=="; you start to learn that the compiler catches most of those mistakes. Unfortunately, if this reduced vigilance leads to you typing "if (varx = vary)", the trick doesn't help, the code compiles, and a bug gets through.

    9. Re:Write C for C programmers by Anonymous Coward · · Score: 0
      if (!strcmp(x,y))
      reads as "if not strcmp x, y", there's nothing wrong with that and it may help the coder to structure her code better. I think we can agree on some horrendous syntax at least
      if (!(!(strcmp(x,y)))
    10. Re:Write C for C programmers by Cuthalion · · Score: 1

      #define assigned(x) x

      The reason it's not baked into any common framework is that if (x) is really plenty good enough!

      --
      Trees can't go dancing
      So do them a big favor
      Pretend dancing stinks!
    11. Re:Write C for C programmers by TheWizardOfCheese · · Score: 1

      What a clearly expressed and beautifully written post! The only thing I have to add is that the question about performance in this case betrays a fundamental confusion in the mind of the questioner. Lurking behind the question is the idea that the "compact" form is somehow cheating, taking advantage of a language loophole; missing is the realization that the two forms are formally identical, having not merely the same effect but also the same semantics. That is why I consider the "ptr == NULL" to be inferior style, and in fact the use of NULL in C generally to be undesirable. The fact is that zero means the null pointer and boolean false identically, by definition. You may not like this, but if you are going to program in C you must accept the fact.

      That is why I always laugh when I see a construction like (expression!=0), made "for clarity." The point is to stamp boolean semantics onto the integer expression ... but wait! The given expression evaluates to TRUE only because it is nonzero. So to make it even more clear, it should be ((expression != 0) != 0) etc.

      --

      "The good reader is a rarer swan than the good writer."
    12. Re:Write C for C programmers by Geoffreyerffoeg · · Score: 1

      I think proper use of idiomatic expressions *enhances* maintainability.

      I was about to say the same thing. I like !ptr better than ptr==NULL, probably because I don't like NULL (is it a keyword? is it a #define? defined as what? I just use 0), and ptr==0 is no better. Besides, the English reading "If there isn't a pointer" is better than "If the pointer equals zero".

      Similarly, "i++" is a lot more readable than "i=i+1" to me. Unless you're writing for students in an introductory course, "i++" is better. And statements such as "int i; i = 0;" are actually less readable than "int i=0;", because people will wonder why you didn't write it the normal way, which distracts them from the program.

      Remember that the most likely future maintainer of the code is you yourself. Write the code the way you'd find easiest to read -- which is normally the way you instinctively write. If you have to write annoying optimizations, write in a comment the most concise yet readable unoptimized code you can.

      As for comments: unless you're writing a language-agnostic textbook, avoid true pseudocode. Language-specific pseudocode like "while (obj.fn() returns something valid) i++;" makes sense, because you're thinking in C already.

    13. Re:Write C for C programmers by mattdm · · Score: 1

      But please, oh, please, don't write this:
      if (!strcmp(x,y))
      Intuitively, that looks exactly backwards from what it's testing (equality).


      Nah, you're just thinking of it wrong -- strcmp returns "difference". So, "if not-different x,y" -- exactly what it says, not backwards at all.

    14. Re:Write C for C programmers by syukton · · Score: 2, Funny

      I've always had a problem with that whole !strcmp(x,y) thing.

      So I made a macro called STRCMP which can be used in a manner which reads better logically. ;)

      --
      Reinvent the wheel only at either a lower cost, greater effectiveness, or your own personal enrichment and satisfaction.
    15. Re:Write C for C programmers by swillden · · Score: 1

      Unfortunately, if this reduced vigilance leads to you typing "if (varx = vary)", the trick doesn't help, the code compiles, and a bug gets through.

      "if (((const foo&)varx) == vary)"?

      I shuddered three times in the time it took me to type that. Doing it in C is even uglier... my fingers just refuse.

      --
      Note to ACs: I usually delete AC replies without reading them. If you want to talk to me, log in.
    16. Re:Write C for C programmers by Anonymous Coward · · Score: 1, Funny

      Fricking Genius! Name a function the exact same name as another function except make it all uppercase and make the behavior the exact opposite! If wonder if this would work for... scanf. I can #define PRINTF for scanf and that will be so much clearer! Or #define MALLOC to free. Or #define TRUE to false.

    17. Re:Write C for C programmers by Anonymous Coward · · Score: 0

      What if C-A-T really spelled DOG. - Ogre

    18. Re:Write C for C programmers by Craig+Davison · · Score: 1

      If you don't know what strcmp returns (<0 for alphabetically lower, 0 for equal, >0 for alphabetically higher) then you really shouldn't be reading C code.

    19. Re:Write C for C programmers by Anonymous Coward · · Score: 0
      However, in your example, I actually prefer "if (!ptr)" to "if (ptr == NULL)", for two reasons. First the latter is more error-prone, because you can accidentally end up with "if (ptr = NULL)".

      I disagree. I always use "if (ptr == NULL)". You see, in this example, it is obvious "ptr" is a pointer and not an integer because of its name. But in general, especially until a foreign maintainer is not familiar with the local naming conventions, "if (ptr == NULL)" makes it very obvious what kind of variable "ptr" is. It leaves no room for that slight doubt. As for "if (ptr = NULL)" I have never had that problem because I always compile with the appropriate warnings turned on. Anybody who doesn't is asking for trouble anyway.

    20. Re:Write C for C programmers by Procyon101 · · Score: 1

      ++i is clearer than i++ even. A bit of a pet peeve of mine.

      I see something like:
      i++;
      and I think "why did he generate a temporary? Is there a side effect to the constructor? What's going on behind the covers? This isn't an issue in c, but in c++ where operator overloading of ++ is common, if your not going to use the temporary, DON'T GENERATE IT. even if the compiler will optimize it away, it is clearer to the reader to see that a temporary is explicitly not needed.

    21. Re:Write C for C programmers by noidentity · · Score: 1

      It's interesting that the "if ( !ptr )" form more directly expresses the intent. One often uses a smart pointer class, like boost's scoped_ptr, which doesn't allow implicit conversion to a pointer, but does overload the ! operator to allow this way of checking its value. With one of these, only the above form works.

    22. Re:Write C for C programmers by swillden · · Score: 1

      I see your point. In my code, and many, many other programmers' code, however, the only time you see anything of the form "if (x)" or "if (!x)" is if 'x' is either a pointer or a boolean variable. If you use good variable names, the name itself should make it completely clear whether it's a boolean or a pointer to something. And without any hungarian nastiness or the like.

      So while I see your point, I don't think it matters.

      --
      Note to ACs: I usually delete AC replies without reading them. If you want to talk to me, log in.
    23. Re:Write C for C programmers by Guy+Harris · · Score: 1
      Nah, you're just thinking of it wrong -- strcmp returns "difference". So, "if not-different x,y" -- exactly what it says, not backwards at all.

      Nah, you're thinking of it wrong -- strcmp returns "result of comparison of strings", in a form that appears to have been designed so that the result is compared against 0 using a comparison operator appropriate for the string comparison being done, i.e. == if you're comparing strings for equality, != if you're comparing them for inequality, > if you're checking whether the first string is greater than the second string, etc..

    24. Re:Write C for C programmers by swillden · · Score: 1

      An excellent point. I have a few smart pointer classes that are the same way... but I never even considered the fact that "if (ptr == NULL)" would be a syntax error with them. I suppose you could fix the problem with a couple of operator==() overloads so that you could compare the smart pointer against a null pointer, but that would also make it possible to compare the smart pointer against a naked pointer, which is often not sensible, depending on the semantics of the class.

      I suppose some operator==() overloads that include an assert() call testing the naked pointer against NULL, to prevent anyone from comparing any other pointer would work. Seems much easier just to include an implit conversion to bool, though, and use "if (ptr)" and "if (!ptr)".

      --
      Note to ACs: I usually delete AC replies without reading them. If you want to talk to me, log in.
    25. Re:Write C for C programmers by sribe · · Score: 1

      Lurking behind the question is the idea that the "compact" form is somehow cheating, taking advantage of a language loophole; missing is the realization that the two forms are formally identical, having not merely the same effect but also the same semantics.

      So well said that it made me wish I hadn't already posted, so I could use the mod points I've currently got to mod it up. I suspect that the pedantic insistence that ptr==NULL is somehow superior style comes from half-baked 2-bit instructors who switched from Pascal to C when the market shifted and never really got over the resentment of being forced by circumstance to use the "inferior" language ;-)

    26. Re:Write C for C programmers by noidentity · · Score: 1

      Yes, it is possible, but not that pretty:

      struct never_defined_t;

      bool operator == ( const smart_ptr& ptr, never_defined_t* null ) {
      return ptr.get() == NULL;
      }

      bool operator != ( const smart_ptr& ptr, never_defined_t* null ) {
      return ptr.get() != NULL;
      }

      (also add in definitions with the arguments reversed, so someone can do
      NULL == ptr and NULL != ptr)

      By using never_defined_t*, smart_ptr can only be compared to 0 (which
      implicitly converts to a NULL never_defined_t*).

    27. Re:Write C for C programmers by tvh2k · · Score: 1

      Interesting, because that exact statement threw off my lab instructor this past term. It wasn't until I typed the statement into a program and showed her the output that she admitted her mistake.

      Quite frankly, anyone who has knowledge of cstring functions should understand the counter-intuitive behavior of strcmp() when testing for equalitiy...especially if they're supposed to be teaching it!

    28. Re:Write C for C programmers by Fnord · · Score: 1

      You could look at it as ptr not being a boolean type, hense ! not making sense. I on the other hand see ptr == NULL meaning "the thing ptr points to doesn't exist". Therefore !ptr easily goes in my mind to "ptr does not exist" which is more semantically correct for most cases. There may be some (pointer arithmetic in particular) where ptr == NULL makes more sense, but they're not the common case.

    29. Re:Write C for C programmers by Anonymous Coward · · Score: 1, Interesting

      > But please, oh, please, don't write this:
      > if (!strcmp(x,y))

      #define strings_match(str1, str2) (!strcmp(str1, str2))

      Much clearer.

    30. Re:Write C for C programmers by po8 · · Score: 1

      Just as importantly, there is some potential for "ptr == NULL" to be wrong. This can happen when your libraries somehow have NULL defined to something other than 0. In the ANSI standard, ((void *)0) and (I believe) also ((char *)0) are safe. For non-ANSI compilers and for ANSI compilers where the definition of NULL involves some other kind of pointer the compiler is entitled to silently not do what you thought it was going to do. In particular, ((FILE *)0) could conceivably cause problems.

      Another way to put this: the C programming language defines the sole invalid value of pointer type to be represented as 0. Thus, operations such as ! on pointer values are required to treat whatever internal bit pattern is chosen by the compiler to be the machine's "null pointer" as if it were a 0. It makes about as much sense to use some bizarre NULL symbol as a representation of 0 as it does to define BEGIN to be "{" and END to be "}". It will distract the reader who understands C, and the reader who doesn't needs fixing anyhow.

      What is NULL for, then? Simple: it's the value returned by certain library calls when they want to indicate an unusual condition. Use it in comparisons where the library specification says it is to be used. Note that this was probably also a bad idea on the part of the specifiers, but it's too late now to fix it.

    31. Re:Write C for C programmers by vrt3 · · Score: 1

      That's exactly how I feel about the issue too.

      I also think the possibility of error is often overstated. I think I've made that mistake only two or three times in the 7 years that I'm programming professionally, and I've seen it about the same number of times in other people's code. In all of those cases I found the bug almost immediately when debugging.

      --
      This sig under construction. Please check back later.
    32. Re:Write C for C programmers by NoOneInParticular · · Score: 1

      Maybe #define BLACK white and get run over at the next zebra crossing?

    33. Re:Write C for C programmers by Geoffreyerffoeg · · Score: 1

      This isn't an issue in c, but in c++ where operator overloading of ++ is common

      Don't you mean in ++c? Why'd you generate the temporary language? ;-)

      In a sense, that's why I tend to use i++. Yes, I use ++i on occasion (e.g., in for (some_strange_iterator i=foo.begin(); ifoo.end(); ++i)) where I especially don't want to generate a temporary. But if it's an int, and it's a statement by itself, i++ is (or seems to me) the standard idiom, since the language itself is called "C++", and most textbook examples on for-loops use i++.

      However, since "i++;" and "++i;" as a single statement have the same intent, and as you point out temporaries and classes are worth considering, I think I'll change my style. I didn't know people think about ++i vs. i++.

    34. Re:Write C for C programmers by Black+Acid · · Score: 1
      I see something like:
      i++;
      and I think "why did he generate a temporary? Is there a side effect to the constructor? What's going on behind the covers? This isn't an issue in c, but in c++ where operator overloading of ++ is common, if your not going to use the temporary, DON'T GENERATE IT. even if the compiler will optimize it away, it is clearer to the reader to see that a temporary is explicitly not needed.
      ++i also reads better than i++. "Increment i" verses "i increment".
    35. Re:Write C for C programmers by Twylite · · Score: 1

      Surely it would be more readable to have STR_EQ, STR_GT and STR_LT macros?

      --
      i-name =twylite [http://public.xdi.org/=twylite], see idcommons.net
  36. My .02 by r_glen · · Score: 1

    In my experience (if you're using a half-decent compiler), ANY "hand-coded" optimization will save you AT MOST a few instructions or clock cycles, and this is only in rare cases. Anyone who really needs the extra .000000001% difference is probably coding it in Assembly already.
    BTW, 'if (!prt)' and 'if (ptr==NULL)' yield the exact same code but I prefer the former because I think it's clearer.

  37. Computers are so fast nowadays by CrazyJim1 · · Score: 1

    I don't worry about something, unless its NP complete, On^2, or running over and over. Its not about individual statements, unless they're nested deep in a loop... In which case its probably best to work in assembly. Its a high level programming language for a reason: You're not supposed to care for the running time.

    If it does matter though, you want to analyze your code for where the slowdown occurs. Once you isolated the part, you can try several tecniques to speed up your code. Pick the one that runs the fastest.

    1. Re:Computers are so fast nowadays by kmak · · Score: 1

      "If it does matter though, you want to analyze your code for where the slowdown occurs. Once you isolated the part, you can try several tecniques to speed up your code. Pick the one that runs the fastest."

      Really? =)

      In any case, computers are fast nowadays, but not nearly fast enough. The difference between an O(N^2) and a O(N^3) or an O(N lg N) algorithm is significant - unless you know for sure that N is never going to get too big. No need to be condescending, but if you only mean linear optimizations, then I mostly agree with you. Otherwise, if you can optimize it by any factor, then by all means, you should.

      And also, you can also take the introspective approach - some algorithms work better for certain sizes, so just stitch them together, and use whatever's better for the problem! (ala introsort)

      I don't know how you can worry about NP-Complete problems, since they're.. well, NP-Complete. Linear optimizations might mean the difference between say, 100 years and 110 years.. but.. =P (though yes, I'm aware some specific cases have good heuristics and/or pseudo-polynomial Dynamic Programming answers..)

      I'm sure I won't be the first one on the forum to say, optimize your algorithm first!

      --

      I'm not the devil.. just his advocate.
    2. Re:Computers are so fast nowadays by CrazyJim1 · · Score: 1

      I was just trying to say that its generally a useless affair to try and write 'compiler efficient' code on a regular basis.

      Its better to write readable code, with nice and understandable variable names. Yet there are times you want to use single letter variable names for speed and uncomplicating things. If all your variable names are long, then it detracts from the ones that matter. I use i,j,k for my loops while someone else may use index_of_outer_loop.

      Then to further matters, you have refactoring which says its ok to lose actual performance if your code is readable. It makes sense when you analyze the total time lost in runtime through all users as being millionths of a second, but minutes/hours in actual coding.

    3. Re:Computers are so fast nowadays by SammyJ · · Score: 1

      Word of advice Jim, Name your variables with the longest names you need to understand the code. The compiler doesn't care how long it is; variable names aren't stored in memory or accessed during runtime (or ever). I've been sitting here scratching my head trying to figure out how a programming language that stored variable names in memory would even work.

    4. Re:Computers are so fast nowadays by CrazyJim1 · · Score: 1

      I wasn't saying that short variable names help in run time. I was saying they physically take less time to type and less concentration. If you use a variable as a gear that you never need to worry about once its in place, then you can name it something short. Since its not named anything specifically, you know its not important. Its a psychological thing that I doubt many people know about.

      Its a twofold gain:
      A: Variables you care about aren't cluttered with the variables that you used and have no further use for.
      B: Typing the variable is faster, and requires less concentration. This frees you up with more time to focus on your code.

    5. Re:Computers are so fast nowadays by Anonymous Coward · · Score: 0

      Not everybody has a fast computer.
      That's a silly, naive comment.

      You're saying it's ok to waste CPU time because it has lots of it. If every programmer took that attitude there'd be no benefit at all in buying a faster machine.

  38. Heck no! by Anonymous Coward · · Score: 0

    That's why I code everything in pure assembly.

    Look for my new OS coming to a computer near you in 2125!

  39. This isn't as important as it used to be by Anonymous Coward · · Score: 0

    When I started programming about, oh, 20 years ago this kind of stuff was really important to me. But these days my number one concern is *maintainability*.

    I write my code in the simplest, shortest, most readable way possible, and then benchmark and optimize after I'm done. 90% of the time I don't even have to optimize.

    I think if you take this attitude, your projects will turn out a lot better. Machines are pretty fast and CPU's do a lot of wacky stuff under the hood.

    Now, if you actually do need the level of optimization you describe, you have only one choice: learn assembly and learn how your CPU works. You have to learn assembly and study the output of your compiler. For instance if you want to know the difference between !ptr and ptr==NULL, compile it both ways and check the output. And repeat whenever upgrading any part of your toolchain. Benchmark it too, because a bit of code that looks like it might be slower might actually run faster on today's CPUs!

    Personally, I would use ptr == NULL because it's clearer what you mean. I only use "!" for boolean values. For example, when testing for the end of a string, I would use "*str == '\0'" instead of "!*str".

    (Note, it's been a while since I've done hardcore C [Ruby is my language of choice these days], but I seem to recall that the C standard says that ptr==NULL is the same as ptr==0 [even if the implementation doesn't use 0 as NULL internally, for some reason], so your two code snippets should be identical I think.)

  40. First, make the program WORK by Anonymous Coward · · Score: 0

    Then, if the program seems slow where it shouldn't, PROFILE. If profiling indicates that optimization should be applied, then and only then start arranging things first so that the algorithms and data structures provide nicer performance. If and only if that fails or is for some reason unapplicable, then you can start looking at things like low-level optimizations. (Pipelining, etc.)

    Most of the time crap like if(!ptr) is actually worse than if(ptr == NULL), since in the first case the pointer is first converted into a boolean value (or, in C89, an int) and then checked against false. If you are working with a compiler that was built after 1990, you'll do well to trust the compiler's own optimization routines over this sort of anal-retentive smartypants micro-optimization.

    (Not to mention that if(!p) is downright evil if the pointer nature of "p" can't be determined from immediate context. And anyhow, avoiding implicit conversions is usually the way to go in any language.)

    1. Re:First, make the program WORK by Profane+MuthaFucka · · Score: 1

      These things aren't converted into boolean values. The CPU has conditional branch instructions that work on integers.

      So, the if (!ptr) is translated into:

      lw $1, ptr
      bne $1,0,after_if ;this is inside the if statement

      after_if:

      Note, I used the one TRUE instruction set for my example - MIPS.

      --
      Fascism trolls keeping me up every night. When I starts a preachin', he HITS ME WITH HIS REICH!
    2. Re:First, make the program WORK by Profane+MuthaFucka · · Score: 1

      Dammit, the fracking semicolon Ashcrofted it all up.

      lw $1, ptr
      bne $1,0,after_if
      ;this is inside the if statement

      after_if:

      --
      Fascism trolls keeping me up every night. When I starts a preachin', he HITS ME WITH HIS REICH!
    3. Re:First, make the program WORK by Anonymous Coward · · Score: 0

      (Damned MIPS heretic. 68k for life!)

      Yeah, in the output this may be. But conceptually the compiler regards it as an implicit conversion, if my recollection of C99 is correct. In theory, with some compilers (or most compilers with all optimization disabled) this may result in odd code, such as:

      tst.l d0
      sne.b d1
      cmp.b #0, d1
      bne .iftrue

      Where you'd expect not to have the sne and the cmp. Admittedly, the question is mostly academic.

    4. Re:First, make the program WORK by Anonymous Coward · · Score: 0

      1. Make it work
      2. Make it right
      3. Make it fast

  41. #asm by snookerdoodle · · Score: 1

    If you're really, truly, deeply concerned about how well a particular piece of code is optimized, the only way to be really, truly, deeply sure is to Do It Yourself for the particular processor you are using.

    Unless it really needs to be optimized, and I speak as a person who reads others' code a LOT, PLEASE go for readability over obfuscility. ;-)

    Mark

    1. Re:#asm by vidarh · · Score: 1
      Yeah, and then there's the issue that most assembly programmers are crap at what they do, and end up doing a worse job than the compiler because they make assumptions about pipelining etc. that are simply wrong. I know there are assembly programmers out there that DO know how to do things right, but most programmers have no business even thinking about trying to "optimize" the compiler output.

      I remember (though not with much fondness) the days of optimizing the M68000 assembly output from one of the Amiga C compilers 12 years or so ago, when I could trivially halve the size of a program just by reading through it and rewriting the code almost as fast as I could type (seriously, I wonder what the f*** they thought they were doing producing compilers that shitty). But modern compilers are getting good enough that it's seldom worthwhile to spend time trying to beat them unless you have spent a LOT of effort improving algorithm choices and profiling first.

  42. code should be written for people to read by SamSeaborn · · Score: 5, Insightful

    "Programs should be written for people to read, and only incidentally for machines to execute."
    - Structure and Interpretation of Computer Programs

    1. Re:code should be written for people to read by IronicCheese · · Score: 1

      Mod parent to 6, Insightful.
      thanks. ;)

    2. Re:code should be written for people to read by Anonymous Coward · · Score: 0

      If I wanted humans to understand my work, I would have been a novelist!

    3. Re:code should be written for people to read by Dogun · · Score: 1

      I wouldn't put a lot of stock written about an abandoned child of LISP.

    4. Re:code should be written for people to read by pyrrho · · Score: 1

      I find that really funny.

      I know where it comes from but... I can just imagine novels written in C.

      Then what happens?...?!

      --

      -pyrrho

    5. Re:code should be written for people to read by eille-la · · Score: 1

      and here is the FREE online version:
      http://mitpress.mit.edu/sicp/full-text/book/book.h tml

    6. Re:code should be written for people to read by Anonymous Coward · · Score: 0

      You mean novels written in Scheme.

      (was (day calm sunny) (street palm-lined))

    7. Re:code should be written for people to read by Anonymous Coward · · Score: 0

      > You mean novels written in Scheme.

      > (was (day calm sunny) (street palm-lined))

      if (love(you, sum(body))) {
      if (love(you, sum(1))) {
      them = FREE;
      free(FREE);
      them = FREE;
      }
      }

      if ((you == BLUE) && (you_know(&place_to_goto))) {
      goto fashion; /* why not? */
      }
      fashion: put_on(the_ritz);

  43. Just look at the assembly by Anonymous Coward · · Score: 0
    You want to know? Easy.

    Just write the bit of code you're curious about in both ways you'd like to compare, then look at the generated assembler. You don't even need to know much about assembler.

    No need to Ask Slashdot about it.

  44. Can be harder in C++ by rrowv · · Score: 1

    I don't believe the compiler can be trusted with more complicated pieces of C++ code, as they can be too hard for a compiler to know for sure that the optimization won't be destructive. The biggest example is when using the STL (or just about any class with iterators like that). Take the follow code:

    for( iterator itr = items.begin(); itr != items.end(); itr++ )
    {
    //stuff
    }

    Will the compiler recognize that the return value of the postfix ++ operator isn't being used, and can therefor use the faster prefix operator? Probably not, because it won't know for sure that the two methods really do accomplish the same thing. While in general this is the case, its possible that someone's code may not operate that way, causing wierd bugs.

    Stuff like this pops up more and more when you make code like this that makes heavy use of classes and templates. Because of that, I don't trust the compiler to figure out it can use "++itr" instead, so I tell it to do that myself. That is just the first one I can think of, but there are many more.

    With that said, you in general want to choose the one that is the easiest to read, even if it is slower. Code maintainability is generally more important than speed IMO.

    1. Re:Can be harder in C++ by SamSeaborn · · Score: 1
      Yeessh .. that for statement is a migraine waiting to happen. Please be considerate to the rest of us who may end up maintaining your code -- your code should be written to be read by a person, and only incidentally to be read by a machine.

      Use objects. This (Java-syntax) is far more readable:

      Iterator iter = items.iterator();
      while (iter.hasNext()) {
      iter.next();
      // do stuff
      }

      Sam

    2. Re:Can be harder in C++ by WWE-TicK · · Score: 1

      There's nothing unreadble about the code rrowv posted to anyone who's familiar with C++ and the STL.

    3. Re:Can be harder in C++ by Anonymous Coward · · Score: 0

      Whiles give me headaches.. for seems so simple, logical and easy to read. Its all spelt out there up top and in plain and simple code. Get a grip you java programmer.. meh!

    4. Re:Can be harder in C++ by whee · · Score: 1

      Doesn't your code also skip the first element? (Also, it's less readable than the parent given the example is C++, and that style is a very common idiom)

    5. Re:Can be harder in C++ by vidarh · · Score: 1
      He IS using objects. Just because you don't know how to read C++ doesn't mean it isn't just as readable to C++ programmers as your example is to Java programmers.

      Besides your example is far less flexible - it requires the iterator to know when the end of the sequence is reached. The C++ approach is to use two iterators to define a range.

      Note also that due to the genericity used in STL, the iterators can perfectly well be anything from plain pointers to a complex object doing losts of calculation - you can trivially use templates to algorithms working on any iterators regardless of what they represent as long as the types you iterate over support the operations you carry out on them.

    6. Re:Can be harder in C++ by vidarh · · Score: 1
      Did you bother to TEST your assumptions above? I did. GCC generates EXACTLY the same output for postfix and prefix ++ with "-O2".

      And gcc is far from state of the art when it comes to optimizing C++ code...

      I agree that it makes sense to use "++itr", but not because I think it'll make any performance difference.

      Your general principle is sound - the compiler WILL have problems optimizing code if it depends on something that isn't available to it at compile time, for obvious reasons. However when you're using templates or the code is otherwise visible modern C++ compilers do a quite good job at optimizations.

    7. Re:Can be harder in C++ by rrowv · · Score: 1

      Quite right, I stand corrected. I had heard arguments that using ++itr was advised (instead of itr++) because the compiler wouldn't automatically convert it to ++itr in this case. My mistake.

    8. Re:Can be harder in C++ by scotch · · Score: 1

      Did you test it with a not trivial iterator class? One that doesn't compile down to a pointer like the std::vector::iterator will? One that has non trivial (and potentially expensive) construct and copy?

      --
      XML causes global warming.
    9. Re:Can be harder in C++ by vidarh · · Score: 1
      The type of iterator should only have a bearing on the result in really bizarre cases, as it is trivial for the compiler to detect that the return value should not be used, and the C++ standard is quite specific about how prefix ++ should behave for the standard iterator categories.

      The prefix version is expected to behave like this: "T tmp = *r; ++r; return tmp;" where T is the value type and r is the iterator. If you look at that it should be obvious why the optimization normally succeeds. Under 12.8.15 of the C++ standard, the implementation is allowed to optimize away the copy construction and construct the object directly into the object it's returned to. If the returned object is never used, no call to the copy constructor needs to be generated at all, even if the copy constructor has side effects. GCC at least does take advantage of that, and will optimize away calls to the copy constructor if the value isn't used.

      You could certainly mess up this optimization by writing an iterator class that explicitly acts differently for prefix and postfix ++ apart from constructing and returning the value type, but then it would also be wrong to blindly switch between the two to optimize the program, and your iterator would be behaving in ways likely to be highly unexpected by users.

      So while there are certainly cases where postfix ++ may end up more expensive than prefix ++, it's quite likely to reflect a bad design, and personally I'd consider it a bug if I ever come across an iterator class that badly behaved.

  45. Not a question that can be asked generally by Sycraft-fu · · Score: 4, Informative

    Each compiler is different. Some will optimise things other won't.

    In general, however, systems are now fast enought that when in doubt, write the clearest code possible. I mean for most apps, speed is not critical, however for all apps stability and lack of bugs is important and obscure code leads to problems.

    Also, for things that are time critical, it's generall just one or two little parts that make all the difference. You only need to worry about optimizing those inner loops where all the time is spent. Use a profiler, since programmers generally suck at identifying what needs optimising.

    Keep it easy to read and maintain, unless speed is critical in a certian part. Then you can go nuts on hand optimization, but document it well.

    1. Re:Not a question that can be asked generally by dbIII · · Score: 1
      Use a profiler, since programmers generally suck at identifying what needs optimising.
      Profiler enters - "Based on psychiatric evaluations this I/O code is a serial killer!"
  46. optimize vs pessimize by Dionysus · · Score: 1

    Sutter and Alexandrescu had some advice about it C++ Coding Standards (I would think it would apply to other languages too).
    Don't optimize prematurely and don't pessimize prematurely.
    Micro optimization is useless unless you know for sure that that particular code segment is a bottleneck. OTOH, there are no reason you should pass stuff by value if you can get away with passing it by reference, or do i++ instead of ++i.
    As someone pointed out earlier in the disccusion, choosing the right algorithm is more important.

    --
    Je ne parle pas francais.
  47. That desperate for a few cycles? Faster box! by Anonymous Coward · · Score: 0

    Already have the fastest box? Wait six months.

  48. When to hand optimize by Ironsides · · Score: 1

    Hand optimize code in places that are called a lot, and places that take a lot of processing power. Use the compiler for tasks that are not intensive. However, if you call one task a lot either as a subrotine or in a loop, hand code that to be as optimized as you can. Likewise, routines that are heavily processor intensive should be hand optimized to improve performance. Optimizing anything else won't provide as much of an over all boost in performance.

    --
    Fly me to the moon Let me sing among those stars Let me see what spring is like On jupiter and mars
  49. Check out the LLVM demo page by sabre · · Score: 5, Interesting

    LLVM is an aggressive compiler that is able to do many cool things. Best yet, it has a demo page here: http://llvm.org/demo, where you can try two different things and see how they compile.

    One of the nice things about this is that the code is printed in a simple abstract assembly language that is easy to read and understand.

    The compiler itself is very cool too btw, check it out. :)

    -Chris

  50. Hand optimization is dying by Anonymous Coward · · Score: 0

    Processor Tech & JIT compilers are killing hand optimized code. Not only that, but hand optimized code is often detrimental on AMD while beneficial on Intel or vice versa.

  51. More like this... by Anonymous Coward · · Score: 0

    if(story->isOnFrontPage())
    {
    postDupe(story);
    }
    else
    if(story->sumitter == "Roland")
    {
    post(story);
    }

  52. That's a Tony Hoare quote, not Donalded Knuth by Dan+Ost · · Score: 4, Informative

    Donald Knuth was quoating Tony Hoare when he said that.

    --

    *sigh* back to work...
    1. Re:That's a Tony Hoare quote, not Donalded Knuth by xlv · · Score: 1

      Yes, I stand corrected, although I guess Knuth popularized the saying a bit more.

      See http://c2.com/cgi/wiki?PrematureOptimization for more details and other famous optimization quotes.

  53. IO Activity is performance killer... by Anonymous Coward · · Score: 0

    Far too many programs reads data from files periodically. Harddrive cycles are extremely expensive, and in my experience, one of the most common reasons for slow programs.

  54. being careful. 2 week rule by Triumph+The+Insult+C · · Score: 1

    if you are going to maintain that code, just be sure you know what it does 2 weeks after you write it

    <sarcasm>'cause you just now wrote it, and i don't know what it does</sarcasm>

    --
    vodka, straight up, thank you!
  55. What are you trying to do? by Mannerism · · Score: 1

    Do you really need your code to run as quickly as possible? If so, by all means, use whatever coding tricks you want. Just be sure to add comments to deobfuscate.

    OTOH, if fast enough is fast enough, then code clarity will pay off far more in the long run.

  56. Not that I have massive amounts of experience... by rivendahl · · Score: 1

    ...but I'd say test your compilers. Find the right fit. If the compiler doesn't optimize or doesn't optimize the way you'd want or expect then change it. I've tried gnu c++ compiler. I like it. But I don't care about optimization. So I didn't pick it based on that. I chose it based on free beer. A buddy of mine said it wouldn't work as well as Borland's. Depending on the task it's better. So he owed me a case.

    Regardless, since coders are a choosey lot, you're best bet in my mind is to play around until you find the one you like.

    I have to say I like the analogy between Embedded versus Desktop. One would think embedded compilers use better optimization but I would also think, based on some code I've seen, that embedded coders also hand optimize as well. Is there such a thing as double optimization?

    Rivendahl

    --
    ... there is nothing that has not already been thought ...
  57. Not Machine Performance but Programmer Performance by RNG · · Score: 1

    These days, unless you're doing something really weird, it's not about machine performance but about programmer performance. For the average application, who cares if some calculation takes 0.005 or 0.006 seconds?

    What however does matter, is the fact that your code is clean, understandable and easily maintained and extended by other programmers.

  58. Quote by Anonymous Coward · · Score: 0

    Someone else said this...

    "Code is not about telling a computer what to do, it is about telling other people what you are telling the computer to do."

    So, what is more intuitive?
    if(!myPtr) or if(myPtr == NULL or if myPtr is null

    C's terseness has only ever served to exclude other people and make them feel inferior.

    1. Re:Quote by Anonymous Coward · · Score: 0

      C's terseness has only ever served to exclude other people and make them feel inferior.

      And, therefore, increase my salary. :)

  59. Write for people first, machines are fast by Anonymous Coward · · Score: 0

    Generally the compiler will do a good job optimizing on code written for human understanding. Remember computers are still getting faster, and that will more than compensate for most of these small tricks you are thinking of. Like that post earlier, a good choice in algorthim is more important that these little guys. So code it up and then see how it performs. If it gets the job done right (always the most important thing), and in a reasonable amount of time, you are finished.

    If perfomance turns out to be a problem, the other trick is to find the place in your program where it spends most of the time (if there is one). Optimize that or part of it will usually generate the needed improvement.

  60. Re:Let me guess by Anonymous Coward · · Score: 0

    1MIPS microcontroller.
    1000 samples per second required.
    Need to gather 4 ADC input values, 4 binary port input values, perform some calculations, perform sanity checks, handle errors and send the digest and status over RS232, plus intercept interrupts in the meantime.
    1000 cycles becomes horribly tight limit. And the compiler doesn't optimize.

  61. It doesn't matter by marcus · · Score: 1

    If you write code and it needs optimizing, you will hand profile and optimize. If it does not need optimizing, you won't.

    Simple.

    --
    Good judgement comes from experience, and experience comes from bad judgement.
    - W. Wriston, former Citibank CEO
  62. You should already know the answer... by David+H · · Score: 1

    Maintainability is much more important than optimization. If you do find a slow section of code, it can almost always be optimized in a way that leaves it maintainable. Real hand-optimization involves using a better algorithm, reducing the number of function calls, reducing branchs, and at worst, adding more variables to avoid performing the same calculations repeatedly within a loop. None of these require you to compete in an obfuscated C contest!

  63. use a good profiler!! by EccentricAnomaly · · Score: 2, Informative

    Trying to optimize in your head rarely does any good... Use a good profiling tool (like Apple's Shark) to find out what part of your code uses the most time and then just concentrate on making that part faster.

    Using a profiler and your own brain you can often significantly improve over what a compiler can do.

    --
    There are 10 types of people in this world, those who can count in binary and those who can't.
  64. "if (0 != variable)" is for wimps by zapatero · · Score: 2, Interesting


    Those that advocate the constant first in if boolean comparisons are the feeble minded who believe ever bit of propaganda and PC reporting they read.

    It's especially annoying to see it done in programming languages like Java where assignments are not even allowed in if statements. When I see java code like this:
    if (0 == x)
    I'm thinking "loser".

    Back to C. And besides gcc since C-99 has issued warnings for assignments in the "if" expression when not embedded in parenthesis.
    example...
    if (x = 3) ... will result in a warning.
    if ((x = 3)) ... no warning.

    1. Re:"if (0 != variable)" is for wimps by Anonymous Coward · · Score: 0

      That's bad, but not as amusing as seeing people do things like:

      if (foo == true)

      Every VB programmer I've ever worked with does that. Kind of sad, really...

    2. Re:"if (0 != variable)" is for wimps by Anonymous Coward · · Score: 0
      Those that advocate the constant first in if boolean comparisons are the feeble minded

      The next time you get an x-ray, you'd better hope that people that developed the x-ray machine software were "feeble minded" rather than unskilled and attitudinally-challenged like you. This forum demonstrates is what I always see here - a mix of code monkeys and professionals. Now pick up you banana and go back to your pen.

    3. Re:"if (0 != variable)" is for wimps by Mattintosh · · Score: 1

      That's because there are 2 kinds of VB programmers:

      1) Stupid n00b programmer that will never grow from n00b-dom into someone riding a clue train (any clue train at all...) These would do something like
      if foo = true then bar
      because they were told to do it that way, and that if they didn't, they'd have their neck wrung.

      2) "Old salt" VB programmers (HA!) that are trying to teach the type from #1. They know that it's all too easy to have problems with VB when you try
      if foo then bar
      and not know what types you're dealing with.

      In fact, I'm not so sure that latter code example is even legal in VB.

    4. Re:"if (0 != variable)" is for wimps by Principal+Skinner · · Score: 1

      Amen! Let me add to that an extract from a blog rant I wrote up a while back.

      Joel Spolsky suggests that one sign of a good programmer is if he writes something like "if (0==strlen(x)), putting the constant on the left hand side of the ==." The recommendation seems to be to put constants on the left side of equality comparisons in general. That way, if you mistakenly write an "=" instead of a "==", it won't compile. But guess what: if you instead put the strlen() call on the left side of this expression, and mistakenly use an =, it also won't compile (yes, I checked it, on a Linux box, gcc2.96 (one of those Red Hat specials)). This example is one that can't give you a run-time error, no matter how hard you try to fuck it up.

      The correct strategy he should be endorsing is: always put variables on the right side of a conditional expression. Of course, this is not possible when both items for comparison are variables. And, as stated above, it's meaningless when neither side is a variable. So I really question the value of acquiring this habit whose use you have to put so much thought into, can't use it all the time, so you have to work even harder to remember to use it; seems you might have better luck simply trying to remember to use == when you mean ==.

      --
      one hundred twenty
      is just enough characters
      to write a haiku
    5. Re:"if (0 != variable)" is for wimps by kybred · · Score: 1
      Talking about putting the constants on the left, I've seen code like this:

      if (MAX_LEN < x)
      {
      ...
      }
      That drives me crazy!

      kybred

    6. Re:"if (0 != variable)" is for wimps by hobo2k · · Score: 1
      I tortured myself for years by witting (666==x) and it never became natural. I suppose the counter argument is that when (x==666) slips out my fingers I immediately notice it. Whereas (x=6) is easy to miss. afaik, every compiler warns about it now, so yeah, it is better to devote your brain to more important things.

      0==strcmp is not bad though. Anytime a small thing and a big thing are related to each other it is good to have the small thing first. It saves time when mentally parsing it. Same with 'if' statements. If one of the blocks is just a couple lines and the other is huge, the small one should be the 'then'.

    7. Re:"if (0 != variable)" is for wimps by Bill+Dog · · Score: 1
      That bothers me as well. But then I'm guilty of practicing something similar, for ranges, as I think the following, e.g., makes it as clear as it can possibly be that a variable must fall within a certain range:
      if ( 1 <= month && month <= 12 )
      {
      ...
      }
      --
      Attention zealots and haters: 00100 00100
    8. Re:"if (0 != variable)" is for wimps by devnull17 · · Score: 1

      The latter is very legal in VB. In every language I've ever seen, the expression in an if statement has to reduce to a boolean.

      In all honesty, VB isn't as bad as people make it out to be. It certainly has a number of glaring weaknesses (particularly VB6, which is still in widespread use), but it's pretty useable as long as you pay attention to the inner workings of the language. Of course, it takes as much time to gain such an intimate knowledge of VB as it would to do so with a "real" language such as C++, so you really have to wonder what the point is.

      I don't think any good programmer uses VB6 by choice (almost all good programmers I know are pretty language-agnostic to begin with), but when you have to use it, it's really not as miserable of an experience as people seem to think.

      Most of the time, at least.

  65. Not always. by game+kid · · Score: 1

    Look at "freeware" programs. Some are made by only one person and as "freeware" usually implies only the binary being distributed, there are cases where only that person (and perhaps the occasional close friend) might see it. Also, some of us (myself) like to compile programs by ourselves just to see what we can do, or even to ready up for the next programming course. I'm can't possibly be the only person who does this. (...right?)

    --
    You can hold down the "B" button for continuous firing.
    1. Re:Not always. by zaffir · · Score: 4, Insightful

      I make my code easy to read for my own sanity. I've lived out this bash.org quote way too many times.

      --
      "Upon attaching the waterblock to my penis, I began to notice that I know nothing about computers." -- JRockway
    2. Re:Not always. by Anonymous Coward · · Score: 1, Insightful

      you all keep talking about clarity, but: why, oh why, is NULL considered to be more clear than 0? it's a #define, for chrisake, and a cast to boot. what could be less clear? equal to zero, not equal to 0, this is a fundamental concept in C. NULL is an artificial conceit added to the language by people who want to create some artificial nullity for pointers. I don't get it. Yes, write for clarity, use a zero

    3. Re:Not always. by Dastardly · · Score: 1

      I make my code easy to read for my own sanity. I've lived out this bash.org quote way too many times.

      Yes, but if it was hard to write, it should be hard to read.

      GRIN!

    4. Re:Not always. by shaitand · · Score: 2, Insightful

      I do too. Unfortunately some of the coding standards floating around make code very difficult to write and to read. There are people claiming that mixed case is a good idea.

      Dear god no, mixed case leads to gobs of errors from nothing more than incorrect case. All code should be lowercase unless some idiot has set an ancient precedent that Thingy(R) should always be all caps, period. This one thing can double the speed at which you write and debug code.

      Next is this BS about self-documenting code. Code is not meant to be self documenting. Proper scoping will prevent names from clashing. Write the most efficient function you can and choose names that make sense in the smallest scope possible.

      And then *gasp* COMMENT the code well. You can even include comments near where a variable or function is to indicate in plain English what it is for! Believe it or not, code should not be self commenting, code is not a spoken language and is a poor medium to use to express messages between people who speak one. Nothing works better than your actual spoken language in complete sentence structures in a comment to remind you what a variable or function is or what a block of code does.

      By_using_variable_nms_that_dnt_lk_like_this 40 times in 6 lines of code you will save enough time writing those 6 lines that you can add a nice comment that says # vnameshort is used to demonstrate a horribly verbose and lengthy variable name in this function. and please for god sake comment EVERY call of a function that is not part of the standard c libraries within 20 lines explaining where it came from! Doing this will not only easier for people who know the project well to see what is happening and where to refer to but it will also help those who are NOT familiar jump in and possibly change one thing.

      Believe it or not, I do not want to read your 100,000 lines of source to make one change. I want to be able to look at the main routine and b-line right from there to the portion of the code I need using the commented function calls.

    5. Re:Not always. by BasilBrush · · Score: 1

      Because 0 is an integer. It's not a pointer value. C may be weakly typed, but it doesn't mean you should confuse types when it's just as easy not to. We use NULL rather than 0 for pointers for the same reason we use FALSE rather than 0 for booleans.

    6. Re:Not always. by EsbenMoseHansen · · Score: 2, Interesting
      why, oh why, is NULL considered to be more clear than 0?

      In C, this is because 0 != NULL. NULL = (void*) 0. This makes a difference in function calls, where calling myfoo(int a) with myfoo(NULL) is a compiler error/warning, but myfoo(0) is legal.

      In C++, NULL = 0. Really. Here's the header from gcc (well, really the kernel):

      #if defined(__cplusplus)
      #define NULL 0
      #else
      #define NULL ((void *)0)
      #endif

      This is because C++ has points to members, I believe (not sure, don't use void* pointers). Instead I use this struct, which IMHO should be included in STL (slightly shortened in the interest of brevity, and written from memory, so may not compile):

      struct Null_ {
      template<typename T>
      operator T*() { return 0; }

      template<typename T, typename S>
      operator S::T*() { return 0; }
      } my_null;

      The first member ensures that my_null can be converted to any pointer other than pointer-to-member, and the last one takes care of those. This method makes the C case above work as it should, i.e. give an error.

      As for clarity, it separates two concepts: The NULL pointer (a pointer pointing to nothing) and 0 (an integer).

      As an aside, I actually prefer !p, since it say to me "If p not a valid pointer....". But I can handle both :)

      --
      Religion is regarded by the common people as true, by the wise as false, and by rulers as useful.
    7. Re:Not always. by BasilBrush · · Score: 2, Insightful
      I'd never employ you. You are wrong on just about every point in that post. You sound like you've not been through many code review processes, if any.

      If you are serious about coding, I recommend you pick up a copy of the book "Code Complete" and read it cover to cover. You need it.

    8. Re:Not always. by joto · · Score: 1
      Dear god no, mixed case leads to gobs of errors from nothing more than incorrect case.

      Huh. What kind of errors are you talking about? Compile-time errors? They are not exactly the main problem when writing reliable software, now are they?

      [Still about not using mixed case]:This one thing can double the speed at which you write and debug code.

      Well, I don't know about you, but my coding speed isn't even remotely limited by my typing speed. If it is, you really need to learn to type.

      Next is this BS about self-documenting code. Code is not meant to be self documenting.

      Of course it is.

      Proper scoping will prevent names from clashing. Write the most efficient function you can and choose names that make sense in the smallest scope possible.

      Yes

      And then *gasp* COMMENT the code well. You can even include comments near where a variable or function is to indicate in plain English what it is for! Believe it or not, code should not be self commenting, code is not a spoken language and is a poor medium to use to express messages between people who speak one.

      I'd rather say: don't bother. Comments should be limited to

      1. The purpose of the code
      2. The basic ideas behind the implementation, perhaps with a link to relevant literature
      3. And if needed, maybe a short explanation of unusual data-structures and/or algorithms, but see 2.

      Specifically, if you create an API, don't document it too much. API's change, and your comments will get out of sync with reality. If the API ever stabilizes, and lots of people start using it, that's the time to start thinking about proper documentation. Because that's the time you don't want to change anything. Look at GTK for example. It's highly succesful, but still not perfectly documented. And still changing!

      Nothing works better than your actual spoken language in complete sentence structures in a comment to remind you what a variable or function is or what a block of code does.

      Exactly. And therefore comments should be limited to a short explanation at the top or bottom of the file, or in a separate document. You don't need to add too many details, as those will change. Give the basic ideas instead.

      and please for god sake comment EVERY call of a function that is not part of the standard c libraries within 20 lines explaining where it came from! Doing this will not only easier for people who know the project well to see what is happening and where to refer to but it will also help those who are NOT familiar jump in and possibly change one thing.

      For the love of God! Please don't! So when the API changes, you have approximately 2 billion places to update comments to get them in sync with reality. Just don't do that! Keep comments in one place, and one place only!

      Believe it or not, I do not want to read your 100,000 lines of source to make one change. I want to be able to look at the main routine and b-line right from there to the portion of the code I need using the commented function calls.

      Believe it or not. I don't want to change comments in 100,000 lines of source for a minor API change, that would otherwise result in 5 edits. Neither do I want to grep through them when trying to find out what needs to change. And I know where I come from. At my last job I was thrown into a project with about 60MB of code made unmaintainable by people following the commenting practices you preach, followed by at least 10 years of maintenance work by different people.

      It was nearly impossible to find out what a given piece of code did, because you would have 30 or so separate places that documented the code, none of them which got it right, because 10 or 20 people had changed the code later. At every edit (and I only added new functionality), the code shrunk because useless comments were deleted first, and useless or obtuse code were fixed or removed later. The code was a total disaster-area of well-meaning but idiotic over-engineering, followed by real-life maintenance work by people totally unequipped to understand the resulting mess. This is software archeology in practice!

    9. Re:Not always. by clarkcox3 · · Score: 2, Informative
      In C, this is because 0 != NULL. NULL = (void*) 0

      Actually, in C, NULL can be (0), just like in C++

      This is because C++ has points to members, I believe (not sure, don't use void* pointers).

      Actually, it's because, in C++, there is no implicit conversion from (void*) to any other pointer type; as there is in C

      --
      There are no tiger attacks in my area and it's all because this rock I'm holding keeps the tigers away.
    10. Re:Not always. by Foz · · Score: 2, Insightful

      Bullshit. He's spot on in many cases (although admittedly a tad overzealous).

      Comments should be used LIBERALLY, albeit intelligently as well. If you do something that isn't intuitively obvious to even the most casual observer, just take 30 seconds to write a fucking COMMENT explaining why you did what you did.

      Believe it or not, eschewing comments because "oh, well, if you want to understand it just read the code" just pisses those of us off who have to come along and clean up your miserable excuse for a codebase... and it sure as hell doesn't prove how studly a programmer you are.

      That doesn't mean half your codebase should be comments, but it does mean that you should at least make a passing nod to demystifying your own attempts at cleverness. I have lots of better things to do than to spend all fucking day picking apart your rabbit's nest of code before I can make a change, add a feature or fix a bug.

      People that honestly believe that "if it's well written it doesn't NEED comments" should be strangled with their mousecord and hung in their cubicles as a warning to the rest.

      -- Gary F.

    11. Re:Not always. by BasilBrush · · Score: 1

      And when you leave school, I won't be employing you either. There are places for comments (almost always in class and function headers.) But if you have a need to sprinkle them liberally, you are not using using meaningful identifiers, not splitting your code up into small functions, or prematurely optimising. It is perfectly possible to write legible code that needs very few comments. But it's not a skill that all coders have.

    12. Re:Not always. by Anonymous Coward · · Score: 0

      C is always:

      #define NULL 0

      in every standards compliant standard C library that I know of.

    13. Re:Not always. by Anonymous Coward · · Score: 0
      I just wanted to say you're totally right. Any code itself that is so complex it needs comments should be rewritten. I'd again refer to the Linux Coding Standards that started this tangent -- Linus's next point after the one quoted states that if a high-school kid can't understand a function it should be rewritten.

      I wouldn't employ that guy either.

    14. Re:Not always. by Foz · · Score: 1

      Lol I left school long long ago, nice to pull that assumption out of your butt though and further that ego.

      Those of us that actually get *paid* to program every day (and have been programming for 20 years or so) don't have time to waste picking apart your 200k lines of spaghetti code because you were too important and too macho to be bothered to put a few comments in. Some day you'll grow up and kick that nasty "I'm so important" habit. Here's a clue... the phrase "it was hard to write, it should be hard to read" is *sarcasm*, not a truism.

      Oh, and I wouldn't work for you anyway. I carefully assess jobs and potential employers, and when they say "oh, we don't have to comment our code" I either take a contracting assignment so I can make the big $$$ fixing all their "perfect" code so that it actually works _or_ I happily go on to an employer who has actually been through puberty and understands that people actually need to *maintain* code and plan accordingly.

      But hey, thanks for worrying about my employment status. If you're ever looking for a job, I'd give you a fair assessment, but I guarantee you if you bragged to me about not having to comment your code you'd be getting a complimentary cheez doodle, a bent business card and a "we'll be in touch".

      -- Gary F.

    15. Re:Not always. by jeanicinq · · Score: 1

      A case in point, do you feel the need to comment what your just wrote in that reply? If you preach the dire need of comments, then I want to see what you preach with everything you write.

      Ok, I know you're about to say, "I meant just program code and not English." Does it mean, for say, that one is not a good writer in English if this one does not also translate their English sentences into Chinese? Kind-of silly for the common case -- don't you think?

      After many years of code digestation, I read code like I read any other written language. There is no need to translate everything written into another language for those who know how to read. I tend to delete others comments just so I can read the code easier.

      Comments in code are only helpful as hints and not helpful to translate the code into English or another language. If you write programs well, there is no need to comment the code. If you write programs well, there is no need to even make sense out of the names of variables and functions; they are only helpful hints and never meant to be spoken english.

      One thing to consider is the amount of money spent to update the comments in code when a simple program change is made. Does one try to justify the need for completely commented source code for revenue?

      If you want to live by comments, go ahead and spend your life in a repeated explanation of yourself or what you have done, for in essence that is what commented code tries to acheive.

    16. Re:Not always. by Foz · · Score: 5, Insightful

      No, you're adopting a black or white approach. You are, in essence, saying that you don't need to comment at all. The original poster was saying that comments needed to be everywhere, on everything. I believe in a middle ground approach.

      I comment things that are non intuitive. I comment things that I *think* may be non intuitive. I comment things that I think someone else might have some difficulty understanding, because I happened to be deep into a code burn and consequently wrote something pretty tight, pretty sweet, but also pretty obfuscated. Finally, I comment things that I think *I* may not understand when I go back and look at the code again 3 months from now.

      I don't comment every single line... I don't comment simple data structures, loops "/* this is a for loop using the integer variable I */" etc which would be stupid. I do however disassemble the complex portions of my code, describe how I'm dispatching events and best of all *why* I decided to do things a certain way instead of a different way.

      I have, however, been handed 30k lines of code with zero documentation and not a single comment anywhere in it, with absolutely no clue at all how it worked and no access to the original programmer and been told "We need such and such fixed|updated|added by friday" and had to spend the entire week basically tracing every single line of code to figure out that the original programmer must have been smoking crack with NO indication of why he wrote things how he did and NO help when he decided to be exceedingly "clever"
      in his code. That time was wasted.

      Would it have killed him to simply put a comment block explaining his event dispatch model? Or to tell me what his functions and methods did and best of all why they did it?

      There *is* a middle ground, believe it or not.

      -- Gary F.

    17. Re:Not always. by jeanicinq · · Score: 1
      #define NULL ( void * ) 0

      That is only needed for compilers that aren't smart enough to know that the value of zero is congruent to nothing, nullity, or no value. That is only confused when the default index for binary starts with 0 for the ordinal first instead of 1, like in positive natural integers.

      Without the #define NULL in the source code, look at just the assembly output. How does one tell the difference between the valid address 0 and the macro-expanded value of NULL to 0? The use of NULL is obscure when it looks the same as something else when compiled.

    18. Re:Not always. by shaitand · · Score: 1

      "But if you have a need to sprinkle them liberally"

      How about doing the rest of us a favor and sprinkling them liberally whether you feel it is needed or not?

      "not splitting your code up into small functions"

      This makes a codebase easier to maintain, not easier to understand. What this means is that if I am not familiar with your codebase I have to refer to some other class or library to find out the interface for EVERY line of your code.

      Modular code is a good thing but it only has a relation to commenting in your own mind buddy. It also is generally overdone by people who express the attitude you are.

      While you think your class is perfect and that you only need to document the interface. I think your class is an ok start and I need to fix half the individual pieces within it or tweak it to turn it into the new class_mine. So please comment it so I can see what each and every portion is doing. Really, English is better method of conveying meaning between humans than code.

      "It is perfectly possible to write legible code that needs very few comments"

      Yes, and legible code should only have a comment or two every 10-15 lines instead of every other line. At particularly cryptic points each line should have a comment explaining it's function (for instance everytime a regex is used there should be a comment next to it saying what it is searching for).

      Commenting 50 lines of code well will take you about 30 seconds when you write it. Those comments will save everyone who reads it several minutes following your code.

    19. Re:Not always. by Surt · · Score: 1

      Mixed case is great. With a good editor it can clarify class and variable names enormously, without creating a typing burden. Then you don't need as many comments to clarify what is going on.

      --
      "Who is the Journal of Quantum Physics going to believe?" --Stephen Hawking
    20. Re:Not always. by jeanicinq · · Score: 1
      The middle ground you want is well written prototypes. The code content beyond the prototypes does not need to be commented. Well written prototypes would allow you to understand the entire program without any code seen. These kind of prototypes do include completely documented states of all input and output values. There does exist a movement to make such prototype documentation as readable as mathematic symbols and equations to avoid the translations, like from english to chinese and so on. Those kinds of symbols, however, are not easy to put in ASCII bounded code.

      What you need is prototypes, not comments.

    21. Re:Not always. by shaitand · · Score: 1

      "Huh. What kind of errors are you talking about? Compile-time errors? They are not exactly the main problem when writing reliable software, now are they?"

      Yes, they use development time that could be used for debugging real problems and writing better software.

      "Well, I don't know about you, but my coding speed isn't even remotely limited by my typing speed. If it is, you really need to learn to type."

      Have you considered that perhaps you need to learn to code? Coding is like speaking, I can speak English faster than I can type it. I can also formulate code faster than I can type it.

      "Specifically, if you create an API, don't document it too much. API's change, and your comments will get out of sync with reality. If the API ever stabilizes, and lots of people start using it, that's the time to start thinking about proper documentation. Because that's the time you don't want to change anything. Look at GTK for example. It's highly succesful, but still not perfectly documented. And still changing!"

      Here is where our opinions differ. Your mentality is why there is so much poorly documented code. The thing is, your not finished updating the API until you have updated the comments. You should be commenting WHILE your coding. The comments are just as important as any functional code.

      "For the love of God! Please don't! So when the API changes, you have approximately 2 billion places to update comments to get them in sync with reality."

      Woah, stop the presses right here. You have misunderstood what I am saying. I'm talking about referencing the library the function is contained in at logical intervals not actually documenting the API with each use! The filename of a library should change rarely enough that this shouldn't be a big deal, in fact if you document these in a standard way you can whip up a script in about 5 mins to change these for you throughout all your sourcecode. This tells me where to look for your function and THERE I will find the updated api comments (these should be updated BEFORE the new api is written and both should be done before a commit.

    22. Re:Not always. by shaitand · · Score: 1

      I find mixed case code harder to read not easier.

    23. Re:Not always. by BasilBrush · · Score: 1, Informative

      You're not old enough to have been working for 20 years, I can tell by your use of language. And you certainly haven't been programming commercially for long if at all. Drop the pretence. And pick up that copy of Code Complete, it will help you. Believe it or not I'm giving you a hint that will help you.

    24. Re:Not always. by Impy+the+Impiuos+Imp · · Score: 1

      > you all keep talking about clarity, but: why,
      > oh why, is NULL considered to be more clear than 0?

      As usual, my intellect so vastly supercedes those around me, I find myself fantasizing about sex with a 16 year old girl's vollyball team.

      Technically speaking, in the C language, pointers are either valid or NULL (neglecting garbage pointers.) NULL is usually -- but not always -- zero.

      So to be correct, one should never test vs. 0, but rather vs. NULL.

      "OK, GIRLS! Practice is over. Let's get into the showers!"

      --
      (-1: Post disagrees with my already-settled worldview) is not a valid mod option.
    25. Re:Not always. by BasilBrush · · Score: 1

      Complete hogwash. Most sections of assembly code could be produced by many different variations of source code. It's not an issue. You'll be making a case for magic numbers in code next.

    26. Re:Not always. by Impy+the+Impiuos+Imp · · Score: 1

      Which, by the way, irritates the hell out of me that some idiots I work with have created "NULLPTR" as a #define. GOD DAMN YOU FOOLS! We already have a null pointer #define. It's called NULL. WTF will you use NULL for if not anywhere you would use NULLPTR?

      "Suzie, it's Debbie. If we hug, we can soap each other's back at the same time. Don't worry. We're platonic, but good, friends, and I'm sure the frank touching of breasts won't induce new and unexpected feelings."

      --
      (-1: Post disagrees with my already-settled worldview) is not a valid mod option.
    27. Re:Not always. by Impy+the+Impiuos+Imp · · Score: 2, Interesting

      > People that honestly believe that "if it's
      > well written it doesn't NEED comments"

      They are lazy, and lack attention to detail. This is a mental escape on their part that assuages their small-frog egos.

      --
      (-1: Post disagrees with my already-settled worldview) is not a valid mod option.
    28. Re:Not always. by WGR · · Score: 1
      Comments that state what the code does are pretty useless, since the code says the same thing.

      But comments that state WHY it does what it does are golden. When I read code I need to know the decisions the programmer made so I usnderstand the reasoning behind it.

      All variable declarations should be commented to explain what they should contain, the assumed range of values they will hold, and whether they contain local scope values (intermediate results) or values used for a longer term (in a database or file or from user etc.). Names don't have to be sentences, but they should not be cryptic. You are much less likely to make a typo in a word you understand than in a meaningless set of letters.

      Clear code is also easier for the compiler to optimize. Reusing variables for different purposes means that the compiler can not optimize the use of the variable away into a register. It neeeds to save it after use so it is available for the second re-use. Names are local to a {} block in C so temporary variables can be optimized away if they only exist within such a block. Good code is also easy to optimize code.

    29. Re:Not always. by BasilBrush · · Score: 1

      Comments go stale. Comments do not update themselves automatically. Comments do not explain the code, they only represent what someone thought about the code at some point in the past. Comments lie. Comments get in the way of doing code reviews. Code doesn't lie. It's far better to write legible code than commented code.

      You say there's only need for comments every 10-15 lines of code, but when functions are rarely over 20 lines, you'll find that you rarely need them except in class and function headers. Yes there are places where comments are needed, and regexes are a good example. but they are rare. Anyone who uses the words "sprinkled" and "liberally" in relation to comments will be hit with a large cluestick at my company.

      As to to our comment about splitting into functions having no relation to commenting, I don't know where to start! If you factor out a block of code into a separate function, you already have a mandatory short comment - the name of the function. It already gives a clue to what that block does. And most of the time you have additional clues in the argument identifiers. But then you also have the one place where you always put comments - the function header comment. With anyone adhering to any reasonable coding standard, the explanation of what that block does will be right there.

    30. Re:Not always. by Bill+Dog · · Score: 0, Offtopic
      I believe I also would not hire you, as you are now. Your overblown rant on mixed case could indicate an inflexibility, and a tendency towards imagining distinctions without differences. There are no "gobs of errors" in either of two things that are merely stylistic differences. If you work at a place that uses CamelCase, you use that, whether you personally think it's the source of all evil in the world or not.

      The belief that the notion of self-documenting code is BS is also troubling. And troublingly defeatist. If you think self-documenting code is unattainable, then you're not going to even try for it. With that belief it would be illogical to strive for descriptive names, may as well be terse and save some typing. When the spoken language is English, at least, and I suspect with most human languages, they actually could not be worse as a medium in conveying rigorously and accurately what code does. Human languages are terribly imprecise, with multiple meanings/nuances for words, plus non-language cues such as facial expression often critical for interpreting the meaning. Why do you think the various diagramming "languages", such as the ones in the UML, were invented if human language was so superior for describing code-related concepts?

      On your commenting comment: If you have to comment a variable, it means that you've failed to think of a sufficiently descriptive name for it. If you have to comment a function (at least on what it does), you've violated function cohesion. I agree that code should be commented well, but define it much differently. They should be (not need to be more than) infrequent. I comment my overall approach. I'll comment a loop that has a fair amount of content, to give a one-line description of what it's for (not what it does -- that's what the code is for). I'll comment major blocks in a function so that it can be quickly absorbed at a high level. I'll comment things like where the API documentation is in error, and you really have to pass foo instead of bar, at least in that version of the API, to get functionality baz, so someone else doesn't come along and wonder who the dodo was, or worse, change it.

      On commenting each and every non- standard library function call, why would I want to waste time doing something twice? Why would I name a function "con", and then have to put a comment above it, and everywhere it's called, saying "see if connected", when I could just name the function "isConnected"?

      --
      Attention zealots and haters: 00100 00100
    31. Re:Not always. by crlf · · Score: 1
      So to be correct, one should never test vs. 0, but rather vs. NULL.

      Bzzt.

      The language defines the null pointer constant to be zero, whether or not the underlying hardware uses all-zeroes. There is nothing wrong with testing against 0.

      Please RTFFAQ
    32. Re:Not always. by BasilBrush · · Score: 1

      Why comment the range of values a variables can contain. Such a comment will rarely be updated when someone decides to change the range. Better to use actual code in the form of debug asserts. At the point when variables change, as pre-conditions and post-conditions for functions, or as an invariant() member function that checks an objects instance variables for limits and consistency. The great thing is that if the limits change, and no one thought to change the assert-as-a-comment, then it'll probably trigger during testing.

    33. Re:Not always. by BasilBrush · · Score: 1

      youfindmixedcasehardertoreadthaneasier? AreYouSureYouFindMixedCaseHarderToReadThanEasier? or_do_you_find_it_easier_with_underscores? Personally I'm happy with mixed case or underscores. But it definately needs one or the other.

    34. Re:Not always. by shaitand · · Score: 0, Offtopic

      "If you work at a place that uses CamelCase, you use that, whether you personally think it's the source of all evil in the world or not."

      Actually I believe that software firms are the source of all evil in the world. Go figure.

      "Why do you think the various diagramming "languages", such as the ones in the UML, were invented if human language was so superior for describing code-related concepts?"

      You would have a stronger point here if we were talking about one or the other. But we are in fact talking about both. Terse function and variable names can convey more meaning than a 20-30 character name when coupled with a comment. If you are going to neglect one area or the other I'd prefer you hand me commented obfuscated perl code than an uncommented attempt at documentation through code.

      "If you have to comment a variable, it means that you've failed to think of a sufficiently descriptive name for it"

      If you have to comment a variable it means you haven't properly commented the code block it is used in or that it comes from somewhere else. A variable name like VB_Int_Table makes perfect sense when used with comments to give context or when defined within the same code block but could actually be damn near anything. If you find yourself using a variable name that is over 30 characters and is actually a phrase seperated by underscores and caps you should be using a comment instead. BTW my rant on mixed case is not exactly a new idea. It is part of what makes the cli on *nix systems usable.

      "I comment my overall approach"

      Always

      "I'll comment a loop that has a fair amount of content, to give a one-line description of what it's for"

      That depends on how you define fair amount of content. It really depends on the content of the lines, but roughly a line or two comment every 10-15 lines is needed. And it is better to use a long comment than a terse one. A terse comment is a greater sin than a terse variable name, that is certain.

      "I'll comment things like where the API documentation is in error"

      Odd, I would correct the API documentation or the API, whichever fits.

      "isConnected"

      hmm, nice. What parameters does it take? It checks to see if something is connected to something. How flexible is it? Does it check to see if I have a tcp connection or a connection in a higher level sense in the protocol? Can is it flexible enough to send a flag and get foo? isConnected is not returning the proper value, in which lib will I find it? Is it one of ours or part of x-api we are using? How about the first time you use it in this block of code you use a standard comment which tells me what file it is contained in?

      If we move a function between libraries or rename a lib we can use a script to automatically update all these references easily. Your function name does not tell me enough to actually use your function or be certain what each of the 6 integers you passed it is for at a glance. Hopefully the comments in the library/headers will tell me and failing that at least I can find the code itself. I might even be able to fix your buggy function call and find out why it wasn't returning the value it should be.

    35. Re:Not always. by shaitand · · Score: 0, Offtopic

      int gmtoffset; #odd, seems easy to read to me
      int GMTOffSet; #difficult to read and to type

      int casecomplex; # Do you find it easier with
      # underscores?

      Seriously, in practice there are times when you use ONE underscore in a variable name because it is similar to another variable name. Of course in practice your codeblock is probably too large or improperly commented if those variable names aren't clear without being that verbose.

    36. Re:Not always. by Anonymous Coward · · Score: 0
      And when you leave school, I won't be employing you either.

      Still searching for someone to watch the fryer while you pinch zits in the Wendy's washroom? Your quest will end some day!

    37. Re:Not always. by BasilBrush · · Score: 0, Offtopic

      Offset is one word. I'd go for gmtOffset and caseComplex. But also happy with gmt_offset and case_complex.

      I'd find it easier to read still without those comments cluttering up the code.

      I would never, ever use an underscore to differentiate between two otherwise identically named variables. Theres something deeply wrong with that suggestion.

      Of course in practice your codeblock is probably too large or improperly commented if those variable names aren't clear without being that verbose.

      On the contrary, one on the big reasons you find the need for comments is you go for non-descript identifiers.

      I think there is a curve that programmers go through in their career. From first learning to program, when they use no comments at all, as it's just small excercises done and then forgotten. Then with the encouragement of tutors they move into the "sprinkle liberally with comments" mode. Then at some point later they'll learn to write code legibly. And finally one day when they are maintaining some code with some particularly out of date comments that confuse far more than they clarify, conflicts that leave you wondering whether the code is wrong or the comemnt is wrong, finally the penny will drop. Finally they'll work out the ultimate approach is highly readable code, with minimal comments. They drop the redundancy, drop the maintainance of two almost parallel streams of information, and stick to one.

    38. Re:Not always. by alw53 · · Score: 1

      My favorite are the standard Java comments like // Public instance methods

      in front of all the public instance methods. // Private static methods.

      etc.

      I've seen way too much Java code where those are the only comments in the file.

    39. Re:Not always. by shaitand · · Score: 0, Offtopic

      " Offset is one word. I'd go for gmtOffset and caseComplex. But also happy with gmt_offset and case_complex.

      I'd find it easier to read still without those comments cluttering up the code.
      "

      Then we have a fundemental disagreement on this that cannot be resolved.

      "I would never, ever use an underscore to differentiate between two otherwise identically named variables. Theres something deeply wrong with that suggestion."

      I'd agree. I said similarly named not identically.

      "On the contrary, one on the big reasons you find the need for comments is you go for non-descript identifiers."

      Comments are harmless in all cases and helpful in most. Believe it or not comments were not invented to hinder programmers and are not evil. Not updating comments as you code is bad programming practice. Commenting is not bad programming practice.

      "I think there is a curve that programmers go through in their career."

      You and every other programmer. And the curve always end with thinking just like the programmer in question does or has the programmer's point of view as the pinnacle with the view getting dated down the road (depending on the programmers stage in his career).

      The truth is that both are right... maybe half the time.

      "wondering whether the code is wrong or the comemnt is wrong"

      Inaccurate comments are the results of bad programming. Don't blame comments because programmers don't update them as they go. You change a line of code with a comment you change the comment too, it is not that difficult. The verbose naming system is the result of programmers who fail to understand that comments are part of the programming, not just sprinkles on top.

    40. Re:Not always. by RWerp · · Score: 1

      Because when you have 64-bit pointers, NULL is not 0, it's 0L.

      --
      "Long run is a misleading guide to current affairs. In the long run we are all dead." (John Maynard Keynes)
    41. Re:Not always. by RWerp · · Score: 1

      You are much less likely to make a typo in a word you understand than in a meaningless set of letters.

      Not always. I'm not a programmer, I'm a scientist. I do however write some numerical code in C and Fortran. I noticed that if I call a variable state_count, half an hour later I may think that I called it state_cnt, or st_count. If I called it scnt, I would simply have to remember that cryptic name, and had it right every time. I think the good approach is to pick names that are easy to pronounce, at least for me.
      I still prefer the first approach, to save myself the trouble of wondering what the Hell stcnt meant 6 month later.

      --
      "Long run is a misleading guide to current affairs. In the long run we are all dead." (John Maynard Keynes)
    42. Re:Not always. by mmThe1 · · Score: 1

      "Would it have killed him to simply put a comment block explaining his event dispatch model? Or to tell me what his functions and methods did and best of all why they did it?"

      Well, may be just like your case, he was also handed over a requirements document and asked to code it all over "by next Friday".

      This does not justify the lack of comments, but due to similar reasons, coders tend to put off the documentation / clear coding part ("Will clean the code all over once I have delivered the first component.."), which usually never gets done unless someone like you gets stuck in the code and decides to add comments for own and others' benefit.

      The cycle continues.

    43. Re:Not always. by God!+Awful+2 · · Score: 1

      Why comment the range of values a variables can contain. Such a comment will rarely be updated when someone decides to change the range.

      I will occasionally write a comment that mentions the range of values just because it probably makes the code easier to understand. I hope the next person to read the comment will be a bit skeptical. I try to include a date when I do this. E.g. "We support up to 10 entries here (as of May 2004) because that's all that will fit in a 1500 byte packet."

      -a

    44. Re:Not always. by God!+Awful+2 · · Score: 1

      Comments that state what the code does are pretty useless, since the code says the same thing.

      Not true! Code that says "i++; // increment i" is obviously useless. But when you comment the overall effect of a block of code, this has several advantages:

      a) It saves the reader the time of figuring it out for themselves.
      b) It acts as a sanity check.

      I don't know about you, but when maintaining code that was written by someone else, I am often faced with a situation where it is clear *what* the code does, but not what it was *intended* to do.

      I.e. there may have been a bug or a poor design decision in the original code, but without a comment, how can I tell whether the code originally did A but someone changed it to do B or whether it was meant to do B but there was a bug. If I find a case where there is a comment that doesn't match the code then I can usually track down the revision history and figure out which way is correct.

      -a

    45. Re:Not always. by a_n_d_e_r_s · · Score: 1

      Bad programmers dont update the comments - good programmers do.

      Bad programmers dont write comments - good programmers do.

      --
      Just saying it like it are.
    46. Re:Not always. by God!+Awful+2 · · Score: 1

      I comment things that are non intuitive. I comment things that I *think* may be non intuitive. I comment things that I think someone else might have some difficulty understanding, because I happened to be deep into a code burn and consequently wrote something pretty tight, pretty sweet, but also pretty obfuscated. Finally, I comment things that I think *I* may not understand when I go back and look at the code again 3 months from now.

      I basically have the same set of criteria as you do and I make an effort to follow them... only to have my hopes dashed when I see my comments removed in future patches.

      -a

    47. Re:Not always. by BasilBrush · · Score: 1

      No, sloppy program is not the explanation behind state comments. They are inevitable. Remember when you did Database Theory? Do you remember the part about emliminating redundant data because it will not stay in sync. It's the same here. All programmers have rate at which they produce defects in their code. If they are in code logic, they are bugs. Now what on earth makes you imagine that when it is not possible for programmers to product perfect code every time, it's possible to produce or update comments correctly? Answer: it isn't. By putting in more than minimal comments, you are actually increasing the number of defects in your code. And the thing is that the compiler and testing will help to remove the defects from the code logic. But they'll tend to remain in the comments, and get worse as the code is touched by other programmers.

      Next time you're tempted to write a comment, stop. Think to yorself "how could I write this code so that it is easily understandable without the comment". More meaningful identifiers? Assert(s)? factoring out into it's own function? Don't prematurely optimise it? Split a long calculation into a number of shorter ones with meaningfully named temporary variables? Make that magic number into a named constant? Use enums? Make those variables that need to be updated together into a new class.

      Heavily commented code is usually bad code. Either because the comemnts are there to explain code that is written in a less than legible way, or because the comments are unnecessary and defect infested clutter.

    48. Re:Not always. by BasilBrush · · Score: 1

      Good programmers understand database theory and the need to eliminate redundant data. Good programmers know that comments cannot be without defects any more than code can be. And that defects are much more likely to be cleared out of code than out of comments. Good programmers can and do write legible code with few comments.

    49. Re:Not always. by Anonymous Coward · · Score: 0

      The macro NULL expands to a null pointer constant. A null pointer constant is a an integral constant with the value 0 or such cast to a pointer type.
      That the vast majority of NULLs are defined as plain 0 is coincidental has to do with the fact that these libraries are often used with C++ as well.

    50. Re:Not always. by dossen · · Score: 1

      Since I do not wish to enter a pissing contest about experience, I might as well admit that I do not have 10-20 years of experience (although I've worked on a decent size codebase). But I still would like to know why on earth you want to use comments to document where functions and variables are defined? If it is objectoriented code, there ought to be at least one IDE, which will allow you to jump directly to the _correct_ definition of functions and variables, without having to keep updated comments, manually opening the right fiel, and finding the right line. For other things, I've never needed more than ctags or similar tools. I'm _not_ saying that it should be hard to find stuff, but why on earth would you keep a record by hand, when it is perfectly possible to do it automatically (after all, the compiler must do it anyway)? Or is your code so dynamic that you never know where a function is from or something? I'm really having a hard time figuring out how this kind of comment could be a net gain (time spent keeping comments current vs. time saved following comments to code vs. just using automatic tools to search/crossreference/hyperlink the code)?

    51. Re:Not always. by BasilBrush · · Score: 1

      Your version:

      const int packetSize = 1500;
      const int entriesAllowed = 10; //We support up to 10 entries here (as of May 2004) because that's all that will fit in a 1500 byte packet.

      My version:

      const int packetSize = 1500;
      const int entriesAllowed = packetSize/sizeof(entry);
      assert(entriesAllowed== 10);

      (That last line only needed if you know some other thing is going to blow up if it isn't 10.)

      Advantage? No need for a sceptical reader. This code says what it does. It gives the exact reason why 10 is the number. It can never become stale. I don't have the date, but I assume you only put that in to give a clue as to how stale the comment is. If the date is important, then the programmer can find it out from the checkin date of the change, or you can add it as a less cluttered comment on the assert.

      assert(entriesAllowed==10); // as of May 2004

    52. Re:Not always. by dehuit · · Score: 1
      Clear code is also easier for the compiler to optimize. Reusing variables for different purposes means that the compiler can not optimize the use of the variable away into a register. It neeeds to save it after use so it is available for the second re-use. Names are local to a {} block in C so temporary variables can be optimized away if they only exist within such a block. Good code is also easy to optimize code.

      Not true for modern compilers. They will easily allocate different registers for variables during different liveranges. Also limiting scope with {} blocks will yield nothing.

    53. Re:Not always. by God!+Awful+2 · · Score: 1

      No. It's more like:

      #define MAX_ENTRIES 10 (in a system header file) ...

      const int entriesAllowed = MAX_ENTRIES;

      Anyway, your example breaks down for anything more complicated than simple integer math.

      #define X 50
      #define Y 71 // Y = ceil(sqrt(X*100))

      -a

    54. Re:Not always. by Anonymous Coward · · Score: 0

      The most enlightening thing I have ever read about commenting code is probably also the most simple:

      Comment the WHY not the how.

    55. Re:Not always. by aePrime · · Score: 1

      In respect to NULL and C++, from Bjarne Stroustrup himself, "Zero (0) is an int. Because of standard conversions, 0 can be used as a constant of any integral, floating point, pointer, or pointer-to-member type. The type of zero will be determined by context. A pointer with the value 0 is called the null pointer and will typically (but not necessarily) be represented by the bit pattern all-zeros of the appropriate size.

      "No object is allocated with the address 0. Consequently, 0 acts as a pointer literal, indicating that a pointer doesn't refer to an object.

      "In C, it has been popular to define a macro NULL to represent the null pointer. Because of C++'s tighter type checking, the use of plain 0, rather than any suggested NULL macro, leads to fewer problems. If you feel you must define NULL, use

      const int NULL = 0;"

      The C++ Programming Language. 2000. Bjarne Stroustrup. Addison Wesley.

    56. Re:Not always. by BasilBrush · · Score: 1

      No, it doesn't break down. This expresses every bit as much as your code snippet does, without a comment.

      const int x = 50;
      const int y = ceil(sqrt(x*100));

      The reason why that broke down for you is that you came up with an expression with no rationality. That's why you didn't comment it properly. If you'd expressed the reason for that value in a comment as you did before, I could translate that to code without the comment. Works every time.

      The other reason is that you are still defining program constants with #defines. Unless you're still working with some embedded system with only a C compiler, that practice has been deprecated in C++ for years.

    57. Re:Not always. by joto · · Score: 1
      "Well, I don't know about you, but my coding speed isn't even remotely limited by my typing speed. If it is, you really need to learn to type."
      Have you considered that perhaps you need to learn to code? Coding is like speaking, I can speak English faster than I can type it. I can also formulate code faster than I can type it.

      If you can formulate code faster than you type, say you have a typing speed of 75 words per minute, and each code-line on average contains five words, that means you will write about 15 lines per minute, or 4500 lines per day (assuming you are efficient for only 5 hours). Divide that by 5 to allow for archaeology, design, debugging, and testing, and you can do about 1000 lines per day. If you have that kind of skill, you are one of the very few super-programmers in this world. From my CVS logs, I'm at about 50 lines per day. Still good, although loc metrics are pretty stupid anyway.

      Here is where our opinions differ. Your mentality is why there is so much poorly documented code. The thing is, your not finished updating the API until you have updated the comments. You should be commenting WHILE your coding. The comments are just as important as any functional code.

      No. Your mentality is why programs become a mess after maintenance. (*I* write perfect code, it's the bastards after me, that can't keep it that way). While what you say is good in theory, programmers will not update comments if they don't have the time! That's a fact, and it doesn't help the situation to blame others. If you want to make them update comments, keep you comments at a minimal level, and keep your comments useful.

      Woah, stop the presses right here. You have misunderstood what I am saying. I'm talking about referencing the library the function is contained in at logical intervals not actually documenting the API with each use! The filename of a library should change rarely enough that this shouldn't be a big deal, in fact if you document these in a standard way you can whip up a script in about 5 mins to change these for you throughout all your sourcecode. This tells me where to look for your function and THERE I will find the updated api comments (these should be updated BEFORE the new api is written and both should be done before a commit.

      It's funny you want to do that. Emacs, vi, and almost all IDE's has that functionality, without needing to write extra comments, or whipping up small scripts. Learn to use the tools you are equipped with, instead of polluting the source code with redundant information!

    58. Re:Not always. by shaitand · · Score: 1

      "By putting in more than minimal comments, you are actually increasing the number of defects in your code. And the thing is that the compiler and testing will help to remove the defects from the code logic. But they'll tend to remain in the comments, and get worse as the code is touched by other programmer."

      I know this will come as a surprise to you. Code is a little different than a spoken language. If I use "an" improperly in a comment, it is an error but will have no impact on the meaning of the comment. The same goes for typos in almost every case.

      And if programmers are being worked hard enough they don't stop to read the comment they just typed you might as well move them in and put a cot in the corner. Let them take a nap. Code is a funky sprinkling of cryptic characters with rigorous syntax that must be followed. The slightest subtle deviation is an error in the code.

      Comments however are the spoken language we have been using since we were three. They are interpreted by humans who automatically ignore 99.999% of errors in them while retaining the correct meaning.

      As for not knowing which is right, the code or the comment.

    59. Re:Not always. by Foz · · Score: 1

      Nice try. However, I assure you I am definitely old enough. Sometimes I wish I weren't. My back frequently thinks I'm quite a bit *older* than that as well.

      Oh, and us codgers use the word "fuck" too. Your generation didn't invent sex, swearing or any other sins either. Get over yourself already... or at least get a better set of Tarot cards because your "jumping to conclusions" skills definitely need a leg up.

      -- Gary F.

    60. Re:Not always. by BasilBrush · · Score: 1

      No I'm not talking about typos. I'm talking about comments that are not in sync with the code. And if your code is really "a funky sprinkling of cryptic characters", then that explains your reliance on comments. It doesn't have to be like that. It's perfectly possible to write legible code.

    61. Re:Not always. by BasilBrush · · Score: 1
      "Your generation" ... "your "jumping to conclusions" skills definitely need a leg up."

      LOL! Spot the irony.

      Gary, it wasn't the word "fuck" that gave you away. Did you even say fuck? It was your patterns of language not your choice of profanities. And your tendancy to prematurely optimise and inability to write legible code gives away your inexperience.

    62. Re:Not always. by cburley · · Score: 1
      My biggest gripe with comments is that they're written by people who aren't technical writers, so they often are ambiguous, misleading, or false.

      I started programming when I was 9. By the time I was in my early 20s, I was a "hotshot". I also wrote lousy specs for my software, but, amazingly, the people in the Tech Pubs department said they were generally the best such specs that R&D was turning out.

      As a result of realizing my comms skills were poor and having an opportunity for a career change, I accepted a job in that very Pubs department, learned the "trade" of tech writing, ended up in management, won a tech-writing award, set some new standards for accuracy and clarity (especially documenting APIs for the OS), and so on.

      Yet, despite all that, I still am quite capable of writing overly long, dense paragraphs, and, if I'm not careful, they can say, precisely and clearly, the opposite of what I intended them to say (that is, a reader can legitimately make the "wrong" conclusion).

      And I've seen comments written by programmers who employ the "terse" style, yet still manage to write comments that could be interpreted N different ways. ("This can't exceed 20" -- which means what, exactly?)

      It's bad enough depending on code written by people with poor communication skills; it gets worse if they also expect me to depend on their prose to understand what is going on.

      Better for programmers to write code and minimal prose, just as I think we'd all prefer tech writers to stick to writing prose and not code (as they often get even sample code wrong).

      --
      Practice random senselessness and act kind of beautiful.
    63. Re:Not always. by Anonymous Coward · · Score: 0

      Are we to believe that in addition to arguing over inane programming details, you're also an expert in dissecting speech patterns?
      PHD in CS and Psych?

    64. Re:Not always. by BasilBrush · · Score: 1

      Gary, posting as an AC? That's desperate.

    65. Re:Not always. by Twylite · · Score: 1

      Thank you for succinctly illustrating why we need licenses for Software Engineers. Let's take a closer look:

      Dear god no, mixed case leads to gobs of errors from nothing more than incorrect case.

      This is a style issue. Everyone has their own idea of what is (or is not) most readable. What is more important, however, is that the chosen style is applied consistently.

      What this also tells me is that you aren't particularly thorough and are prone to making assumptions, which are really bad traits for a developer. You should work on that.

      Next is this BS about self-documenting code. Code is not meant to be self documenting.

      Perhaps you need to find out what self documenting code is. It is about making code obvious and readable, so that you don't need to *gasp* COMMENT code everywhere. And it does consider notions of scoping and choosing sensible variable names within the context.

      Write the most efficient function you can

      Write the simplest function you can. It is always the easiest to get right, and the easiest to maintain. If you have a performance issue, chose a better algorithm first, and only then move on to improving code effeciency. Otherwise you end up with a huge and hard-to-maintain code base, that requires lots of *gasp* COMMENTS so that you can understand what's going on, because "efficient code" tends to be less readable.

      code is not a spoken language and is a poor medium to use to express messages between people who speak one

      Code is in fact an excellent language for communicating accurately at a low level. Spoken language is often poor at this level, but is excellent for conceptual communication. Thus a comment should describe in spoken language the algorithm that is implemented, but the implementation should be (largely) self documenting and easy to follow (assuming you are familiar with the algorithm).

      By_using_variable_nms_that_dnt_lk_like_this 40 times in 6 lines of code you will save enough time writing those 6 lines that you can add a nice comment that says # vnameshort is used ...

      But there is trade-off between the time you take to write your function, and the time it will take many different maintainers in the future to figure out what it does. Trying to remember the meaning of half dozen short variable names while you interpret someone else's code is not a recipe for efficiency.

      Meaningful variable names don't have to be long; in fact the best ones are short, accurate and unambiguous.

      Believe it or not, I do not want to read your 100,000 lines of source to make one change. I want to be able to look at the main routine and b-line right from there to the portion of the code I need using the commented function calls

      This is not surprising. It is what most developers want to do. Dive right in and fiddle. Without knowing what's going on, of course: you have no idea what effect your change is going to have on the other 99,800 lines of code.

      --
      i-name =twylite [http://public.xdi.org/=twylite], see idcommons.net
    66. Re:Not always. by Surt · · Score: 1

      It may be harder to read for a few people. Perhaps it takes a bit of training. But I think there can be little doubt that the possibility of longer variable and method names enables potential improvements in code clarity, and reduce the need for redundant documentation. Mixed case helps to support this, while still supporting coding efficiency via CamelCase (CC) short cut typing.

      --
      "Who is the Journal of Quantum Physics going to believe?" --Stephen Hawking
    67. Re:Not always. by Foz · · Score: 1

      Not sure what you're talking about, but I haven't posted anything as an AC. Nice jump to conclusions *again*.

      And last time I checked, I haven't been writing code for you to review, so you're really reaching when you say "inability to write legible code". You're definitely qualified to make such an assumption, having seen zero lines of my code.

      But... thanks for playing (and yes, I'm nearly 40, and have been doing this for 20 years, so again you are quite wrong).

      -- Gary F.

    68. Re:Not always. by shaitand · · Score: 1

      You really need to work on your logic. Your statement that I make assumptions is an assumption itself. And although you are rude, arrogant when the only evidence submitted indicates you don't qualify to be entitled, and rude I will respond briefly.

      Lets cut to the chase, writing clear code is a given and was before this nonsense about self documenting code came about. The problem is comment avoidance. We have comments for a reason and because coders are too lazy to change them along with the code the relate the entire "self documenting code" nonsense arose to justify it. I suspect your one of those coders who hates taking the time to update comments.

      Also, it may come as a shock but unless a program is poorly written, any code change that does not change an API should have NO effect that is not within a screenful of text from the code being changed. OO or not code should be modular and the modules should have blackbox type interfaces. Believe it or not a coder should not have to become intimate with your project to change "Initializing Floogenbooper..." to print "Go go gadget Floogenbooper...".

      Basically, I agree that code should be easy to follow by itself. But poorly written code and well written code should be commented equally. Having written your code clearly is no excuse for not commenting it thoroughly.

      One simple test is that contrary to what you posted, one should be able to LEARN an algorithm one has no prior knowledge of from reading the code and corresponding comments. When writing code one should not assume that the one who reads it will have familiarity with anything but the language that you are coding in.

    69. Re:Not always. by Twylite · · Score: 1
      writing clear code is a given and was before this nonsense about self documenting code came about. The problem is comment avoidance.

      The essence of self-documenting code is to write in a style that reduces the need for comments. Don't obfuscate your code in the name of efficiency or of proving how damn good you are. Use straightforward control structures and meaningful names, and all of the comments that describe what the code is doing go away, leaving you with high-level descriptions of what a block of code is intended to achieve and the approach that it takes.

      I suspect your one of those coders who hates taking the time to update comments.

      You suspicion is incorrect. Unless of course you're referred to the /* add 1 to i */ comments, which do (understandable) piss me off.

      Also, it may come as a shock but unless a program is poorly written, any code change that does not change an API should have NO effect that is not within a screenful of text from the code being changed.

      This is one of those things I hear all the time from juniors. The fact is that the only time this statement is true is when you are rewriting part of a function to make it more clear or more efficient. Both are relatively uncommon activities. Bug fixes or additional functionality, which are far more common, do result in a change in the API (even if it is too subtle to be readily noticed).

      Believe it or not a coder should not have to become intimate with your project to change "Initializing Floogenbooper..." to print "Go go gadget Floogenbooper...".

      Ah, so the User Interface and/or contents of a log are not part of what you consider an interface? You have chosen to believe than an API is merely a set of calls and their parameters. But it's not. It's also the effect those calls have on supposedly unrelated parts of the system.

      Does the log parser know about your change? Have all User Interfaces been updated to ensure you use "Go go gadget" consistently? This is stuff that many programmers don't think about because they've convinced themselves that "black box" programming is the solution; but they forget that there is more going into and coming out of the black box than a C function call.

      --
      i-name =twylite [http://public.xdi.org/=twylite], see idcommons.net
    70. Re:Not always. by shaitand · · Score: 1

      "Don't obfuscate your code in the name of efficiency"

      Say that when the same functions stop requiring greater resources because of the current trend that fast development is more important than efficient development. That is only true in the corporate world.

      "The essence of self-documenting code is to write in a style that reduces the need for comments"

      Nothing reduces the need for comments. We do agree at least that a comment like /* add 1 to i */ is stupid. Comments should not explain how to code in a given language.

      "The fact is that the only time this statement is true is when you are rewriting part of a function to make it more clear or more efficient. Both are relatively uncommon activities."

      I imagine they are on teams who believe that self-documenting code is more important than how well the code actually performs its function!

      "Bug fixes or additional functionality, which are far more common, do result in a change in the API (even if it is too subtle to be readily noticed)."

      TRIVIAL bugs are fixed by changes in the API, you catch most of these bugs the first time you write the code, usually when commenting the code you wrote. Additional functionality usually involves extending the API and it is generally simple to extend the API and maintain compatiblity with the old API.

      "Ah, so the User Interface and/or contents of a log are not part of what you consider an interface?"

      If I change Initializing Floogenbooper to Go go gadget it is my INTENTION to change the user interface and/or log entry. Why else would I do it?

      If your using my C function the only thing you can count on is the parameters I accept and the type of value I return. You cannot assume the content of those returns! That is just bad programming.

    71. Re:Not always. by DeadScreenSky · · Score: 1

      I do however write some numerical code in C and Fortran. I noticed that if I call a variable state_count, half an hour later I may think that I called it state_cnt, or st_count. If I called it scnt, I would simply have to remember that cryptic name, and had it right every time.

      I think the main key with that is just to be very consistent in your variable names. I make it a habit of using full words 99% of the time in my variables, for example. A better IDE might really help, too.

      --
      There is no excellent beauty that hath not some strangeness in the proportion. -- Francis Bacon
  66. Optimize after measuring by asrb · · Score: 1
    Generally speaking*, you should trust the compiler to do the micro optimizations. Stick to using good algorithms, clear code and sensible object allocation. Only after measuring critical sections should you delve into optimizing low level code, and you should keep your optimizations as narrowly focused as possible.

    Keep in mind that the guys who wrote the compiler's optimization code are experts at this sort of thing. In most cases, they know quite a bit more than you do about it; as long as your code is clear enough for the compiler to figure out, it'll probably do better than you could. I recall reading an example somewhere years ago, maybe in Code Complete, about two source listings. There was the original vanilla version and the hand tweaked code. Although the tweaked code was more 'optimal', and ran faster without compiler optimizations, the vanilla code ran much faster when optimizations were turned on. This is because the original code was clear enough for the compiler's optimizaiton code to understand and do something much more clever with.

    * Obviously, there may be some domains, such as embedded, wherein this may not apply. The embedded experts can comment here :)

  67. Bah! by GillBates0 · · Score: 1

    Only sissies use compilers. Real men code in binary.

    --
    An Indian-American Hindu committed to non-violent thought/speech/action alarmed by the global explosion of radical Islam
  68. Backwards approach to optimization by Anonymous Coward · · Score: 0

    Like others have said, legibility of code comes first. Those tricks may have been useful in the early 80s, today they will save a negligible amount of processing time.

    Instead, you should first focus on writing correct code and optimize later. If anything, you should optimize I/O access and memory management. The if (!ptr) trick may save a clock cycle here and there, while your program writing to disk when it doesn't have to could cost you six orders of magnitude more.

    Still, there is no formula. The most sensible approach is to write correct code with a modular design. Later, when the need arises, you can optimize the relevant modules only.

  69. Why write shortcut code... by __aaclcg7560 · · Score: 1

    Unless someone is writing code for an embedded device that usually has strict memory and/or timing requirements, why write shortcut code at all?

    I think writing clear, understandable, human-readable code should be a priority over writing code that might be optimized to the hilt by the compiler but very difficult to read and comprehend. This is something that my programming instructors and most textbooks have emphasized over the last few years.

    1. Re:Why write shortcut code... by Anonymous Coward · · Score: 0

      For a real C programmer !ptr is *more* readable than ptr == NULL.

      And the compiler doesn't give a flying fuck whether form you use.

      Good luck. You still have a lot to learn...

  70. Look at the code produced! by rufusdufus · · Score: 1

    All you need to do is look at the code that is produced by the compiler to know if optimizations of these sorts are important. I think you will find that the commercial compilers will make efficient code in almost all cases, especially on simple cases like the ones listed in the article.
    Once upon a time I was a crack assembly programmer optimizing clock cycles and memory hits, but at some point in the 90's, the compilers started to write better code than I could without significant effort. Compilers now know all about cache efficiency and pipelining and never forget to use that special code sequence to save a memory cycle.

    The upshot is, you should trust the compiler and code for clarity.

  71. DATA access by Anonymous Coward · · Score: 0

    Personally, in your example, I prefer the former incarnation. The == makes me look twice to figure out to what you are comparing.

    Anyway, the only thing I really worry about any more is data locality. Say you have a 2D matrix foo[x][y]. Matrices get linearized in memory. If you loop rapidly "across" the grain performance will be poor and it's difficult for compilers to optimize this away (assuming you aren't writing trivial code with array sizes that are known at compile time). If you are really stretched for bandwidth between the processor and the RAM and you have a higher dimensionality then pointer+offset will be faster than using [][[][][][] access.

  72. I prefer it neat.... by mrtom852 · · Score: 1

    Hehe, having seen some truely awful code where I work (in Java too!) I've always been amazed that our apps run quickly let alone at all. I think unless you are writing some intensive processing loop go for the neat code.

    From another point of view though I've always found clever optimisations very interesting (eg. pixel plotting).

  73. Desktop vs. Embedded platforms by sixpaw · · Score: 1

    A quick note on the desktop vs. embedded compiler issue, since nobody seems to have touched on that: in my experience it makes virtually no difference. An embedded application is more likely to use some judicious hand-tuned assembly when needed for speed, but compiler optimizations are generally comparable between the two platform categories -- not surprising, since many if not most embedded compilers are derivatives of GCC and have the same optimization core anyway.

  74. Dated Question by gregarican · · Score: 1

    This line of thinking is (sadly perhaps) dated. I am thinking back in the day when code had to be painstakingly optimized to be stored and executed with minimal hardware resources. Like those video games squeezed into 4 KB of ROM. Nowadays most of the languages folks use are high level programming types. Newer programmers hardly worry about malloc types of things and the nittty gritty. This might not be the best way things are evolving, but with the hardware power and resources that are out there it's true.

  75. Don't ask slashdot by Beek · · Score: 1

    Ask a profiler. Write the clear code, and profile it. If there's a performance problem, then optimize. If you don't think your optimizations will show up when profiling your app, then your optimizations are worthless.

  76. Don't micro-optimize, macro-optimize by Anonymous Coward · · Score: 0

    Don't even bother with this kind of stuff, for simple things like this the compiler will generate adequate code for you if you do one thing or another. If you focus exclusively on the small things, you tend to lose focus on the bigger picture. Case in point, recently a co-worker was so obsessed with optimizing the logic in an "if" statement to be faster once compiled that he ended up writing logically incorrect code.

    If you want to write fast software you are much better to think about the overall design and choose a design/datastructures/algorithms that are efficient. You can hand-optimize the crap out of a O(N) search, but my compiler-optimized O(log N) search is going to kick your butt.

    Also, everyone knows that its if (NULL == ptr) :)

  77. How important is this? by ShamusYoung · · Score: 1
    An additional question you need to ask is: does it matter? A section of code would need to be part of a REALLY heavily-used loop or recursive function before it would have even the slightest effect on performance, unless your target platform is really old.

    I've worked with code that needed to be high-performance. For instance: converting texture data in memory, which is a loop executed (texture size) ^ 2 times, and so it gets used a lot. I've tried a lot of things on these loops to speed them up, but things like (!ptr) vs. (ptr == NULL) are so slight I can't even measure their effect on a loop called a million times. So, over the course of a million trips through the loop, the net savings (if there was any) was less than a millisecond. Shaving less than a millisecond off of something that takes ~400ms is an almost worthless "optimization".

    I've experimented with other things as well, such as using an unsigned char instead of int if I know the value won't exceed 255, and for me the difference is always too small to matter (or even measure) on today's processors.

    Of course, every application is different, and I'm sure in many cases it DOES matter, but I would make sure this is something really, REALLY CPU intensive before I started worrying about (!ptr) vs (ptr == NULL). Code readability is important, and you don't want to make sacrifices just so the menu pops up 1ms faster for the user.

    --
    --This sig is in beta. Please let us know abut any errors you find.
  78. Indeed by Man+in+Spandex · · Score: 1, Insightful

    Short variable names indeed. Some book authors make me laugh.

    A few books of programming that I've used, they all use the infamous i counter name in their for loops and then, they come up and say that you have to give variable names that make sense, and then you see again the for int i...

    1. Re:Indeed by zarr · · Score: 1

      Maybe int i does make sense for a counter. Especially if you're consistent, then every time someone sees an i in your code they will know it's a for-loop counter.

    2. Re:Indeed by Man+in+Spandex · · Score: 1

      How this is troll? Seriously. I'm still in the C.S program but when I go around helping friends with their programs and that I see this exact same thing, the use of short variables, I tell em "it makes your life a shitload easier if you gave every variable a meaningful name".

      This is because for now our programs are like a few hundread lines so it's not bad but my english teacher said on day one that we have to develop good habits so I figure that since we're in school doing programming, we mind as well start getting good habits when it comes the time to plan and code. If you ask me, the style you choose when writing programs is "friggin" important.

    3. Re:Indeed by Anonymous Coward · · Score: 0

      'i' is short for index. it's used everwhere in math/stats/cs, get used to it.

    4. Re:Indeed by alexo · · Score: 1

      > A few books of programming that I've used, they all use the infamous i
      > counter name in their for loops and then, they come up and say that you have
      > to give variable names that make sense, and then you see again the for int i...


      Using "i" for an index variable is perfectly sensible and natural for anybody with a math background (and don't forget that algorithms are math).

    5. Re:Indeed by wayne606 · · Score: 1

      Long variable names and using "foo == NULL" rather than "!foo" sometimes makes code harder to read rather than easier. Also it takes longer to type and that slows down code production, so I use i and ! whenever possible... :-)/2

    6. Re:Indeed by Theatetus · · Score: 1

      What's a better name for an index (which usually translates into a table or array subscript) than "i"?

      --
      All's true that is mistrusted
    7. Re:Indeed by Rew190 · · Score: 2, Informative

      Variables named "i" or "j" are typically used for iterating through loops. I find most programmers tend to stick to this convention, so if I'm reading through someone else's code and glance at an "i" or a "j," I know it's going to be used as a loop or iterator of some sort.

      For example, if you just saw "FIELD_COUNT" by itself without code, would you have a good idea what sort of object that was knowing anything else? (A static variable). If you saw "_count"? (Instance variable). "getCount"? (Accessor method)

      So in that sense, yes, it is meaningful. You'll pick up on things like that when you start coding larger projects with other programmers.

    8. Re:Indeed by lgw · · Score: 1
      i means an integer index in a loop, and j for a loop inside that loop. Perfectly self documenting, as everyone knows the idiom. The same applies to n for a integer variable used to hold an intermediate result in a calculation.

      Long variable names are clutter when the variables represent a very simple concept. Please use
      foo.next()
      and not
      foo.getTheNextFoo()
      for goodness sake!
      --
      Socialism: a lie told by totalitarians and believed by fools.
    9. Re:Indeed by Anonymous Coward · · Score: 0

      How this is troll? Seriously. I'm still in the C.S program but when I go around helping friends with their programs and that I see this exact same thing, the use of short variables, I tell em "it makes your life a shitload easier if you gave every variable a meaningful name".

      Short variable names make much sense when you instinctively know when you're looking at something called "i" it's a loop variable, yes? Take some more math classes and you'll see where these are derived. But no, most programmers didn't adopt them for no reason. It's actually much simpler than reading code where some doofus specified "loop_iterator" as a var name (an experienced programmer will probably think there is more to the variable than just an immediate loop).

      This is because for now our programs are like a few hundread lines so it's not bad

      It's not anything, kid...

      I figure that since we're in school doing programming, we mind as well start getting good habits when it comes the time to plan and code.

      Yes, readability included and being one of the most important aspects of coding. You won't really appreciate that until you have to read someone else's code, spanning a few classes and a few thousand lines.

      If you ask me, the style you choose when writing programs is "friggin" important.

      It's only important if your style is very poor or against-the-grain.

    10. Re:Indeed by jeff4747 · · Score: 1

      Variables named "i" or "j" are typically used for iterating through loops

      And I'm one of the people that absolutely hate to when people use them.

      i works just fine for a simple loop. But then you get someone using i, j, ii and jj inside a bunch of nested loops. It's very hard to figure out which counter means what. Instead, use something like iRecordCount, iInputTokenPos, etc.

    11. Re:Indeed by jeff4747 · · Score: 1

      What's a better name for an index than "i"?

      Something meaningful. iRecordCount, for example.

      In a simple loop it doesn't matter, but as soon as you start nesting loops i, j, k, ii, jj and so on become very difficult to follow.

    12. Re:Indeed by CaptainBaseballbatBo · · Score: 1
      Instead, use something like iRecordCount, iInputTokenPos, etc.

      And get insta-sued by Apple?

    13. Re:Indeed by penguinoid · · Score: 1

      Like everyone else has said, i, j, k, x, y are all very common as counters. Since everyone uses them, they do have meaning, and since they're short they do not clutter.

      However, I find that I sometimes unconsciously write a 1 instead of an i. Am 1 the only one who does this?

      --
      Don't waste your vote! Vote for whoever you want, unless you live in a swing state it won't matter anyways
    14. Re:Indeed by bnenning · · Score: 1

      i works just fine for a simple loop. But then you get someone using i, j, ii and jj inside a bunch of nested loops.

      Multiply nested loops can be confusing no matter what you name the indexes, and are often a sign that you're trying to do too much in one place. i and j are fine, and maybe k in unusual circumstances. Beyond that, I'd look at refactoring more than just the variable names.

      --
      How to solve most of our problems: 1.Lots of nuclear plants. 2.Cure aging.
    15. Re:Indeed by virtual_mps · · Score: 1
      What's a better name for an index than "i"?

      Something meaningful. iRecordCount, for example.

      *puke*

      In a simple loop it doesn't matter, but as soon as you start nesting loops i, j, k, ii, jj and so on become very difficult to follow.

      There's your real problem. If you've gotten to 5 nested loops in a single function you desperately need to refactor the code.
    16. Re:Indeed by Anonymous Coward · · Score: 0

      The person who programmed three or more nested loops should take a lesson in data structures and run time.

      But come on... "very hard" to figure out nested loops?

    17. Re:Indeed by ebyrob · · Score: 1

      Am 1 the only one who does this?

      We all gotta be unique right?

      My trick is stopping at green lights (and sometimes running reds). Be glad your quirk is not life threatening.

    18. Re:Indeed by Theatetus · · Score: 1
      In a simple loop it doesn't matter, but as soon as you start nesting loops i, j, k, ii, jj and so on become very difficult to follow.

      I usually avoid "j" for orthographic reasons (except in Forth, where "i" and "j" are defined by the language as the indexes of the two innermost "for" loops), but I use i or k for every for loop I have ... and if I'm nesting more than 2 loops that means I've let this function get too complex.

      --
      All's true that is mistrusted
    19. Re:Indeed by penguinoid · · Score: 1

      Actually, that one was intentional (and in any case I wouldn't care. It has happened a few times in code, though, and it makes for a most unique failure).

      Be glad your quirk is not life threatening.
      It could be, if I were working on medical software or shuttle program.

      --
      Don't waste your vote! Vote for whoever you want, unless you live in a swing state it won't matter anyways
  79. Stupid question by PrismaticBooger · · Score: 2, Insightful
    I have been coding in C for a while (10 yrs or so) and tend to use short code snippets. As a simple example, take 'if (!ptr)' instead of 'if (ptr==NULL)'. The reason someone might use the former code snippet is because they believe it would result in smaller machine code if the compiler does not do optimizations or is not smart enough to optimize the particular code snippet.
    That's simply inane. Why don't you check the assembly your compiler generates? If your're really up for shits and giggles, compare it to a C compiler from 10 years ago.
    IMHO the latter code snippet is clearer than the former, and I would use it in my code if I know for sure that the compiler will optimize it and produce machine code equivalent to the former code snippet.
    So why are you asking here? Check what your compiler generates. Incidentally, I find the former more readable. While you might be under the illusion that people do use it as an optimization technique, many simply find it easier to read and write. It's a widely accepted and understood idiom for checking pointer validity. And in C++, it has the benefit of being able to look the same whether ptr is a smart pointer or a raw pointer.
    The previous example was easy. What about code that is more complex? Now that compilers have matured over years and have had many improvements, I ask the Slashdot crowd, what they believe the compiler can be trusted to optimize and what must be hand optimized?
    Write readable code. Ask a profiler what you need to optimize.
  80. Premature optimizations by hamsterboy · · Score: 1
    There's optimization, and there's premature optimization. I'm no Paul Graham zealot, but he's got it right here; until you find out exactly which part of your program is the bottleneck, you're likely wasting your time.

    Instruction-by-instruction optimization by hand is only productive for guys like John Carmack, where each nanosecond really does count. If you're really worried about this, why not just write it in assembly?

    Hamster

  81. Optimizations vs Readable Code. by TheDruidXpawX · · Score: 1

    IMO, It's better to start out in your development with the most readable code. Once you have created something larger, you have to go back and analyze what portions of your code can benefit from a optimized re-factor as opposed to which portions of code a refactor would only squeeze in a few ticks. In addition, as compilers get better, your optimizations may only slow down your program in newer compilers, or introduce unusual bugs.

  82. More important question by jmcmunn · · Score: 1, Insightful


    I think that the more important question is "Should I bother to hand optimize my code at all?" since as you pointed out we don't really know how the compiler is going to optimize everything. It could take your perfectly optimized code and ruin it completely, thus wasting all of the time you spent optimizing.

    Personally, I try to write code that is easily readable by myself and others. If it isn't readable by someone in the future, it does no good IMHO. I say write the code how it is easy to read, and let the speed of modern processors, and the advancement of compilers do the hard work.

    Now, of course I don't mean you should write terribly slow algorigthms just to be neat and tidy, you should still take the time to think of a good/clean/fast snippet of code as well.

    1. Re:More important question by MBraynard · · Score: 0, Offtopic
      Heyu -

      You do the referral in my sig and I will do yours - just shoot me an email when you have done it at mattatbraynarddotcom.

      I already got the Ipod and Xbox free. Good luck.

    2. Re:More important question by jmcmunn · · Score: 1


      Uh, yeah we can't do the same offer for each other! I also have gotten several iPods, some cash from offercentric, and a PS2. It's nice when these sites actually work eh?

  83. Hmm. by Anonymous Coward · · Score: 0

    I think it's a bid ridiculous that you're contemplating trying to optimize the case for "ptr == NULL" versus "!ptr".

    Even *if* (and this is a *big* if) the compiler produces slightly different code based on the two, I very, very highly doubt that there will be a significant noticeable performance difference.

    It's far better, IMO, to make the code legible. And, I think that it will be far more to productive to optimize asymptotic complexity (e.g., trying to write an O(n) replacement for your O(n log n) algorithm) than trying to fiddle with such minor things like this.

  84. Just write in machine code by sxmjmae · · Score: 1

    What the hell do you need a compiler for.

    Just program you code directly in machine language and it will be as efficient as you can write it.

    Or if you must use a compiler use FORTRAN or some other old language that has had the compiler crunched for effecieny.

    --
    My Sig indicates the end of the comment I posted.
  85. Only hand optimize what matters by HalWasRight · · Score: 2, Insightful
    • "Premature optimization is the root of all evil" -- C.A.R. Hoare

      "This mission is too important to allow you to jeopardize it." -- HAL

    Seriously, why would you waste your time obfuscating your code when you don't have too? Unless you know through profiling that detailed statement level code is bad then you are shooting yourself in the foot.

    This isn't to say that when making architecture level decisions that you shouldn't optimize. O(N^2) is bad, Um'Kay? O(N) is alright for small N, but O(log N) is better when you know you'll have a significant N. That's the stuff a compiler can't do for you today.

    Once you've profiled, and you know something is critical and can be done better and matters, then start obfuscating. There is a lot you can do in C to optimize, especially with DSP codes, so resorting to ASM should only be done for the most extreme cases.

    --
    "This mission is too important to allow you to jeopardize it." -- HAL
  86. This is an old debate by Kombat · · Score: 1

    The answer in the past was debateable, but usually ended up concluding that you are better off focusing on writing clear code, and letting the compiler handle the optimizations.

    Nowadays, compilers are extremely sophisticated, and can perform very convoluted (and yet, ultimately efficient) optimizations that even the most seasoned programmer wouldn't devise. I've tried this myself with several different compilers, where I code the same algorithm the "clear" way, then re-do it, trying my damndest to make it tight, compact, and efficient. When I compared the output bytecodes/assembly, they were identical. In the former case, the compiler made all kinds of optimizations anyway. In the latter, the compiler had still come up with some optimizations that I hadn't thought of, and in some cases, ignored my own optimizations in favour of an even more efficient way.

    Trust your compiler. A helluvalot of thought has gone into them, and they can optimize far better than you can ever dream to.

    --
    Like woodworking? Build your own picture frames.
  87. Trash in, Trash out by dauthur · · Score: 1

    Think of it this way: Someone had to program and compile the compiler itself, so if he puts no shortcut-enabling features into it to help with performance and whatnot, then he's going to get junk. What do you think he'd want from his own program, junk or perfection?

  88. Take a look at the ASM listings by Dan+East · · Score: 1

    Take a look at the ASM listings. If you're using VC++ then you will have to set the compiler to generate ASM listings in the project settings.

    You don't have to know hardcore ASM to be able to compare how good of job the compiler does with examples such as the one you provided (!ptr vs ptr==NULL).

    Dan East

    --
    Better known as 318230.
  89. Vanilla Code by karniv0re · · Score: 1

    I've always been told that it is best to write vanilla code and to trust the compiler to optimize for you. The compiler is much happier with plain ol' code. It says, "Hey! I know what to do with this!" Rather than some elaborate crap you've written because you think it'll be faster. That's when it says, "Ack! WTF am I supposed to do with this? Oh well, here goes nothing..."

  90. Stick with clear code. by /Wegge · · Score: 1

    I once made an experiment with some long forgotten version of gcc. I tried two pieces of code against each other:

    (while *to++ = *from++);

    vs.

    while (1) {
    to[i] = from[i];
    if (0 == from[i]) {
    break;
    }
    i = i + 1;
    }


    For some strange reason the second version came out ahead by a very slight margin. The generated code looked more or less identical to me at the time, so I expect it was a caching issue. Nevertheless, unless you have proven that > 90% of execution time is spent in a very localized part of your program, don't bother optimizing.

    --
    //Wegge
    1. Re:Stick with clear code. by hpa · · Score: 1

      Actually, the reason the second version came out ahead is probably because you're on an architecture with a penalty-free base+index addressing mode, and the compiler only generated one increment in the second case.

    2. Re:Stick with clear code. by cakoose · · Score: 1

      Ideally, the compiler should do the same thing. On the other hand, it is possible that the compiler only used the access-and-increment instruction in the second case, simply because it was less obfuscated.

      In any case, induction variable analysis is a pretty standard technique and so there's no reason to use raw pointers in most simple loops. If the usage crosses procedural boundaries, then your particular compiler may or may not help you out there.

  91. if (!ptr) vs if (ptr == NULL) by unkaggregate · · Score: 1
    My experience with this is that with dumber C compilers, if (!ptr) will generate assembly like:

    mov ax,ptr
    or ax,ax
    jz _skip_if

    but if (ptr == NULL) will generate:

    mov ax,ptr
    cmp ax,0
    jz _skip_if

    For most compilers it's about the same. With compilers for 386/486/Pentium there can actually be a speed advantage when using !ptr along with other logical operators because the compiler will use assembly language instructions like SETZ which sets AL to either 0 or 1 depending on the Z flag in one instruction instead of 3.

    I think previous posts have a point about how NULL isn't necessarily (void*)0, but I have yet to see such a compiler (Can anyone name one?) so I'm generally in the habit of using !ptr.

    I have however used an old DOS compiler where !ptr doesn't detect NULL pointers properly when used with far pointers and I must explicitly compare against NULL (Mix C compiler v2.x if I remember correctly).

    1. Re:if (!ptr) vs if (ptr == NULL) by fishbowl · · Score: 1
      "I have yet to see such a compiler (Can anyone name one?)"

      After many years of asking old guys and/or teachers and colleagues, I have come to the conclusion that no such thing exists. But it *could* exist, if nothing in the spec requires it to work. But isn't the boolean null pointer compare expressly allowed by ANSI C?

      But there's this:

      1.14: Seriously, have any actual machines really used nonzero null pointers, or different representations for pointers to different types?

      The Prime 50 series used segment 07777, offset 0 for the null pointer, at least for PL/I. Later models used segment 0, offset 0 for null pointers in C, necessitating new instructions such as TCNP (Test C Null Pointer), evidently as a sop to all the extant poorly-written C code which made incorrect assumptions. Older, word-addressed Prime machines were also notorious for requiring larger byte pointers (char *'s) than word pointers (int *'s). The Eclipse MV series from Data General has three architecturally supported pointer formats (word, byte, and bit pointers), two of which are used by C compilers: byte pointers for char * and void *, and word pointers for everything else. Some Honeywell-Bull mainframes use the bit pattern 06000 for (internal) null pointers. The CDC Cyber 180 Series has 48-bit pointers consisting of a ring, segment, and offset. Most users (in ring 11) have null pointers of 0xB00000000000. The Symbolics Lisp Machine, a tagged architecture, does not even have conventional numeric pointers; it uses the pair (basically a nonexistent handle) as a C null pointer. Depending on the "memory model" in use, 80*86 processors (PC's) may use 16 bit data pointers and 32 bit function pointers, or vice versa. The old HP 3000 series computers use a different addressing scheme for byte addresses than for word addresses; void and char pointers therefore have a different representation than an int (structure, etc.) pointer to the same address would have.

      --
      -fb Everything not expressly forbidden is now mandatory.
  92. The 3 Steps to Good Code Development by afroncio · · Score: 1

    A good programmer once told me that the 3 steps to writing programs are:

    1) Make it work.
    2) Make it right.
    3) Make it fast.

    Most people never get past step 1. Unless runtime issues are severely limiting your ability to debug, optimizing is the step you take when you have nothing left to do. :-)

  93. Mod Parent Up(TM) please. by game+kid · · Score: 1

    Just look at IE, still modifying its old code (from the versions so far) to stay compatible with old Web pages and programs that use its WebBrowser control. It's gotten far more secure but still has a long way to go; it'll need teh ol' teardown & rebuild to compete with Firefox and malicious users.

    --
    You can hold down the "B" button for continuous firing.
  94. Devise an appropriate test by Medievalist · · Score: 2, Informative


    Back when I was doing real-time programming in FORTRAN-II on a PDP-11/34, I was able to very slightly decrease execution time by changing "divide by two" instructions to arithmatic shifts and "square root" operations to "power of 1/2" (because x^.5 = sqrt(x)).

    Since those instructions were in a loop that was running 80,000 times per second, this meant that I could get more data when destructively testing rocket motors... in the end, I got a 40% increase in processing speed that was worth a whole lot of money to the company. AND it got me a raise ;) so don't tell ME little increases in efficiency aren't worthwhile!

    The answer to your question is TEST your unique combination of hardware and software, find out what works better/faster/more-elegantly, and use the most human-readable form that you can afford to given your unique requirements.

    If you are doing real-time digital data acquisition involving usecond events, you will probably end up with some pretty cryptic source code, so be nice and put in lots of comments.

    If you are programming an office automation application, your code should probably be readable by kindergarteners, since you won't have very difficult performance requirements.

    1. Re:Devise an appropriate test by fishbowl · · Score: 1

      "don't tell ME little increases in efficiency aren't worthwhile!"

      A 40% increase in processing speed is not a "little increase" and there's not usually the sort of low-hanging fruit opportunities to make that much difference these days.

      --
      -fb Everything not expressly forbidden is now mandatory.
    2. Re:Devise an appropriate test by Anonymous Coward · · Score: 0

      Most people think sub-millisecond improvements are worthless, my post was intended to show that's not necessarily true. It depends on where those microseconds are being saved; if a 50% increase in execution speed on a single operation results in a 40% overall increase in efficieny, well, you already understand.

      I'll have to disagree with you about the availability of "low hanging fruit", though - I haven't seen a program that couldn't be easily speeded up in years. Frequently it's not worth the effort, but it can be done.

      Perhaps you have the good fortune to work in a better environment than I do, or maybe you work more with user-interactive code.

    3. Re:Devise an appropriate test by fishbowl · · Score: 1


      "Perhaps you have the good fortune to work in a better environment than I do, or maybe you work more with user-interactive code."

      Back-end business software, sales and bookkeeping stuff. Our goals are geared more toward reliability and successful deployment than any kind of optimization. I often wish I worked in an environment where performance mattered, because I know how to make processes more efficient and I enjoy doing that.

      --
      -fb Everything not expressly forbidden is now mandatory.
  95. What's the point... by thewils · · Score: 1

    ..in optimising something like a manual data input routine to save a couple of nano-seconds. If there's a core function repeated several million times and _must_ run quickly then write the damn thing in assembler in the first place.

    No, write for clarity assuming an idiot is going to maintain your code - that idiot could likely be you...or me :)

    --
    Once I was a four stone apology. Now I am two separate gorillas.
  96. You are the only person this entire discussion by Anonymous Coward · · Score: 0

    to suggest this.

    You LOSE.

    1. Re:You are the only person this entire discussion by fitten · · Score: 1

      NO YUO!!1

  97. you've been programming c for ten years by soybean · · Score: 1

    and you don't know how to read come asslember and check for yourself?

  98. doesn't matter anyway by sribe · · Score: 1

    The reason someone might use the former code snippet is because they believe it would result in smaller machine code if the compiler does not do optimizations or is not smart enough to optimize the particular code snippet.

    On modern CPU architectures there won't be a speed difference even if the compiler is brain-dead. Personally I use if (!ptr) because I think that is the more clear form ;-)

  99. Clarity is more important by jdog1016 · · Score: 1

    For the example that you gave, you should write (variable == NULL) because it is easier for anyone reading your code to understand. It is also kind of logically strange to say (!variable) if variable is not a boolean value, because that logic operation implies that it is.

    For other examples like that, the same goes. In this day and age, minute optimizations are not worth putting in if it will degrade the clarity of the code, which is far more important. In any case, modern compilers will make such optimizations for you.

  100. not in c++ by ufnoise · · Score: 1

    You may not know if ptr is a smart pointer in c++. An operator!= would then have to be written for every type the smart pointer class would interact with.

    Therefore you should do.
    (ptr != 0)

    1. Re:not in c++ by drxenos · · Score: 1

      Except that there are not so called "smart pointers" defined by Standard C++.

      --


      Anonymous Cowards suck.
    2. Re:not in c++ by ufnoise · · Score: 1
      Except that there are not so called "smart pointers" defined by Standard C++.

      An auto_ptr is part of the standard template library (STL) and it is a kind of smart pointer. The STL is a c++ standard. Unfortunately in can't be used in containers. Boost http://boost.org/ has an excellent collection of smart pointers which may become part of a future c++ standard.

    3. Re:not in c++ by drxenos · · Score: 1

      I would not call auto_ptr smart by any stretch of the would. It has a lot of problem. Besides, it does would with !=, so does not fit your argument. BOOST is not part of of the standard, so also do not fit your argument. By the by, the BOOST libraries that are going into the next release of the standard have already been chosen (though I'm not privy to that info.)

      --


      Anonymous Cowards suck.
    4. Re:not in c++ by drxenos · · Score: 1

      Sorry, it's early, first cup of coffee, and didn't proof read. I hope you get the gist.

      --


      Anonymous Cowards suck.
    5. Re:not in c++ by ufnoise · · Score: 1
      I would not call auto_ptr smart by any stretch of the would. It has a lot of problem. Besides, it does would with !=, so does not fit your argument. BOOST is not part of of the standard, so also do not fit your argument. By the by, the BOOST libraries that are going into the next release of the standard have already been chosen (though I'm not privy to that info.)

      Really, I guess Josuttis is incorrect in his book when he refers to an auto_ptr ". . . as a kind of a smart pointer that helps to avoid resource leaks when exceptions are thrown." You are right though, it is pretty useless. It also appears that the auto_ptr implementation does not include operator's == and !=.

      Thanks for the info about the boost library. I am hoping to see more useful smart pointers in the next STL. Even if the boost smart pointers don't become part of the standard, I would recommend them instead of rolling your own.

  101. And Profile It! by njcoder · · Score: 1
    I agree. For some embedded and real time applications it's important to be able to have the tightest code you can. But for the vast majority of stuff, it's not going to make any difference if you halve the time it takes to generate a 100ms string that gets fed into a 2sec database query.

    Best advice is to code in a readable and consistent format. Profile your application after you're done and work on any real sore spots then. Let your experience give you some ideas on optimizations when you architect the system where it matters.

    80-90% of your code won't need optimization in the real world, profile it and find that 10-20% that does. That will make a big difference.

    1. Re:And Profile It! by oringo · · Score: 1

      Even on embedded systems, unless it is ABSOLUTELY necessary, I would still code for maintainability and portability in sacrifice of performance. Think about porting your applications and revising it in the future when new platforms are available, you'd rather have a clear but slow code than a fast but hard-to-maintain code.

    2. Re:And Profile It! by lgw · · Score: 1
      There are a lot of tricks that you can expect to be portable, however. But I guess that's more a case of finding the code the compiler will optimize properly, rather than bypassing it entirely. For example, for a 32-bit variable writing
      (X<<8)&(x>>24)
      should get you the register rotation operation that most platforms can do in one instruction (and that there's no C operator for), but will still technically work on any platform. It's not as obvious that you're rotating x 8 bits to the left as the assembler instruction would be, but it is portable.

      --
      Socialism: a lie told by totalitarians and believed by fools.
    3. Re:And Profile It! by mlyle · · Score: 1

      You mean (x<<8) | (x>>24).

      This only works if x is declared unsigned, too; else sign extension can bite you.

    4. Re:And Profile It! by Emil+Brink · · Score: 1

      Shouldn't that be |? Consider for instance x = 42 = 0x0000002a. Now, x << 8 is simply 0x00002a00, but x >> 24 is 0. And since x & 0 == 0 for all x, the result becomes 0 rather than the expected 0x00002a00. Just my two bits of Friday night debugging. Enjoyed the trick though.

      --
      main(O){10<putchar(4^--O?77-(15&5128 >>4*O):10)&&main(2+O);}
    5. Re:And Profile It! by Anonymous Coward · · Score: 0

      > (x>24) [corrected from parent]
      > should get you the register rotation operation that most platforms can do in one instruction (and that there's no C operator for)

      I've seen this in a language where there were functions for bitwise operations. bitand(), bitor(), bitxor(). So this function was implemented (in a library, not built in like the previous) as, you guessed it, bitrot()

    6. Re:And Profile It! by eric76 · · Score: 1

      Why not just define a macro or inline function with a descriptive name?

    7. Re:And Profile It! by Harik · · Score: 1

      Wow, well, as 30 million people pointed out, it should be |, not &. However, I tested something entertaining: Putting a static inline roll(a, b) in a header, making it switch on b and using 32 case: statements. GCC knows exactly what to do. wherever I used it, it replaced the entire inline construct with a roll() call. Hell, if I used it with constants, GCC eliminated the entire roll instruction and simply pre-computed the constant value. I'd give this a big vote of "Write legible code, profile when you're done IFF it's slow." The compiler is a shitload smarter then you are.

  102. Premature Optimization... by Anonymous Coward · · Score: 0

    ...is the root of all evil. Stop wasting your time wondering about whether or not you should "hand optimize" and run the damn profiler.

  103. off track by Jodka · · Score: 1

    Worrying about 'if (!ptr)' vs 'if (ptr==NULL)' is not how you optimize code.

    There are three steps to optimizing code:

    1. Instrument your code to find out in what routines it is spending most of its time.

    2. Optimize the places where it spends the time. Choose a better algorithm, do the work in the background if it suspends user interaction, precompute and do table lookup, substitue an approximation if that would suffice. There are many many tricks. Trying to second-guess the compiler is not one of them.

    3. Goto 1.

    --
    Ceci n'est pas une signature.
  104. I have been programming in C++ for a while now... by Anonymous Coward · · Score: 0
    and using smart pointers and here's the code for NULL:
    const // this is a const object...
    class {
    public:
    template<class T> // convertible to any type
    operator T*() const // of null non-member
    { return 0; } // pointer...

    template<class C, class T> // or any type of null
    operator T C::*() const // member pointer...
    { return 0; }

    private:
    void operator&() const; // whose address can't be
    // taken (see Item 27)...

    } NULL; // and whose name is NULL
    Now if you still think that if (!ptr) is evil than the bad guys have won
  105. Don't bother by m50d · · Score: 1

    If it needs optimization so much that you can't trust the compiler to handle it, you should be coding it in assembly.

    --
    I am trolling
  106. Premature optimization by soft_guy · · Score: 1

    Premature optimization is the root of some evil.

    Frankly, I'd code it as:

    if (NULL == ptr) {
    }

    And then use the profiler later to see what needs to be optimized.

    --
    Avoid Missing Ball for High Score
  107. I think a good way to put it is.... by unkaggregate · · Score: 1
    Just write the damn code!

    Seperate things out into functions and get it to work first. When your program works then worry about optimizing it, one subroutine at a time.

  108. look about 3 or 4 posts down by CarrionBird · · Score: 1

    A winnar is me!

    --
    Free Mac Mini Yeah, it's
  109. Sometimes it's worse by Autonomous+Crowhard · · Score: 1
    I once worked with a guy who had the same problem you have. He would write the most insane, convoluted ode possible in the name of optimization. His code was completely unmaintainable. We even tried showing him that his code was longer/slower at the assembler level.

    Don't forget that compilers are designed to optimize normal code constructs. If you come in with something truly bizzare the compiler might just make things worse because it doesn't know what to do.

  110. YOU ARE OUT OF YOUR MIND by Sneakums · · Score: 1

    Trust a compiler? A heartless assemblage of algorithms and logic? Are you insane??

  111. More wordy != clear by Anonymous Coward · · Score: 0

    Using ==NULL instead of ! doesn't make anything clearer, unless you don't know C well enough to know what ! does. In my opinion, bulking up code with unnecessarily longer idioms and whitespace actually makes code harder to read.

  112. No lower than the big-O level by Murmer · · Score: 0
    f you're optimising your code at anything lower than the big-O level you're wasting your time. Full stop.

    If you don't know what that means, you're wasting everyone's time.

    --
    Mike Hoye
  113. NOT is ugly by Xtravar · · Score: 0

    In the first case, I could see a dumb compiler actually using the NOT operation and then testing for zero, whereas in the second case you're just testing for zero explicitly.
    Then again, I could see a dumber compiler testing against zero twice in the second case.

    But these aren't really concerns with the good compilers available to us today, so just use which is clearer.

    Honestly, I wish C had perl's 'unless' operator for these cases, because the ! is just aesthetically unpleasing.

    --
    Buckle your ROFL belt, we're in for some LOLs.
  114. interesting aside.... by Anonymous Coward · · Score: 0

    Sorry, this may be horrible OT...

    Several years ago, I was in the position to hire a software developer. I asked for code samples, and this kid gives me a print out. I swear to $DEITY there wasn't a single carriage return in the C code he showed me. When I asked about this, his reply was "I like to write tight code."

  115. Everyone should... by Shamashmuddamiq · · Score: 1
    ...be required to write a non-trivial optimizing compiler for a popular language before they are allowed to program at all.

    Then they will know what the compiler can and can't optimize and will know what to put their effort into.

    One time I was talking to a guy who was writing a program in assembly and asked why he wasn't using a higher level language. He told me it wouldn't be fast enough. So I asked him if he does strength reduction and loop invariant removal by himself. His reply: "Huh?" If he doesn't appear to understand such simple common compiler optimizations, I'm almost positive the compiler would have done a better job than him. I didn't tell him that, though.

    --
    ...just my 2 gil.
  116. This kind of optimization is mostly bad by jridley · · Score: 1

    I went through a phase where I tried to get every last little bit of speed out of everything. Problem is, that often leads to harder-to-maintain, or less correct, code.

    I don't believe in the camp that says "screw optimization, just buy a faster CPU". However, I also don't think it's worth sacrificing readability or portability to chop out a few cycles here and there.

    Use your optimization brainpower on choosing and implementing faster algorithms; that has the potential of making vast differences in the speed of your apps. As for individual lines of code, do what is most readable and correct and portable.

    BTW, I prefer "if (NULL == ptr)" - put the constant first. Slightly less readable, but will not compile if you accidentally type "if (NULL = ptr)". Once you get used to this it's not a problem to read, but it saves me a bug a few times a year.

  117. My personal favorite C obfuscation by andrewm · · Score: 1

    int a[10];
    7[a] = 1;

    I had to deal with a large project that was written entirely with this assembly-like syntax.

    Understanding some programmers' code is hard enough. Optimize for readability.

    1. Re:My personal favorite C obfuscation by fishbowl · · Score: 1



      "I had to deal with a large project that was written entirely with this assembly-like syntax."

      I'm sure if I saw that I'd want to change every single array operator like that to a reference syntax. I'd also have strong words with the person who did it -- "I know you learned that you could do this in school, but just because you know how to abuse the syntax doesn't mean you should do it in production work."

      --
      -fb Everything not expressly forbidden is now mandatory.
  118. Language paradigms by alexo · · Score: 2, Insightful

    > I have been coding in C for a while (10 yrs or so) and tend to use short code snippets.
    > As a simple example, take 'if (!ptr)' instead of 'if (ptr==NULL)'.
    > The reason someone might use the former code snippet is because they believe it would result
    > in smaller machine code if the compiler does not do optimizations or is not smart enough
    > to optimize the particular code snippet.


    No programmer believes that.
    In C, NULL is #define-ed to 0 and the "!" operator also compares against zero so every compiler should generate exactly the same code for both.

    > IMHO the latter code snippet is clearer than the former, and I would use it in my code

    Actually I prefer to write (and read) the former and I do find it clearer, mostly because it is idiomatic in C et al.

    Another good reason is that the former works better in C++ because it enables you to substitute "smart" objects for plain pointers and use them in a more natureal way (especially in templates).

    (Aside: most platforms that have C compilers also have deccent C++ compilers)

    > if I know for sure that the compiler will optimize it and produce machine code equivalent to the former code snippet.

    See above. There is nothing to optimize.

    1. Re:Language paradigms by fishbowl · · Score: 1

      There have been compilers that don't do the right thing when turning a NULL pointer type into a boolean expression, but if there's anyone using one of those now, they have a long, long list of weird compatability things that they are forced to do anyway.

      But from a conceptual point of view, I have a problem with that line that evaluates a pointer as a boolean expression. For one thing, I'd bet the submitter a box of Krispy Kremes that he's using gcc, which does exactly the same thing with the comparison operator as with the boolean eval.

      >Actually I prefer to write (and read) the former
      >and I do find it clearer, mostly because it is
      >idiomatic in C et al.

      Agreed, but it is a very bad habit that carries into strongly typed languages. You're asking an object to give you a boolean representation of its state, again, a conceptual no-no if the object happens to be a null ref, even if it does tend to work, and even if you like the way it looks.

      --
      -fb Everything not expressly forbidden is now mandatory.
    2. Re:Language paradigms by Anonymous Coward · · Score: 0

      >but it is a very bad habit that carries into strongly typed languages

      Ah, but it carries perfectly well into Javascript.

      In Korea, only old people use strongly typed languages.

  119. Optimization is not the issue by Anonymous Coward · · Score: 0

    Actually, I am using the second form a lot in C++. Consider this:

    Error error=dosomething();
    if(error==0)
    handle_error();

    and this:

    if(Error error=dosomething())
    handle_error();

    The second form gives the variable error a shorter scope, thus preventing misuse (as in: 'oh! I need a temporary variable. Let's recycle error, as it is not used anymore.' Yes, that does happen quite often, unfortunately)

    Along the same lines:

    if(Resource resource=getresource()){
    use_resource(resource);
    }

  120. Don't pre-optimize by saddino · · Score: 1

    Write your code so that it's readable (to you, now and always) and understandable (to others if it's not just yours). Really, you're not going to gain anything trying to beat the compiler these days. After your project is done, then profile: chances are your bottlenecks will be much larger in scope than whether (!ptr) of faster than (ptr == NULL).

  121. clearly written code will probably perfom better by Anonymous Coward · · Score: 0

    Given that most of code's life is in the maintanance portion of the life cylce. I beleive that clearer code will perform better in the long run regardless of the optimizer. The reason that I hold this belief is that future programmers will be more likely to make efficient modifications to code that they can easily understand. A lot of programmers fear modifying code that they don't thoroughly understand and will often make mods in a manner that avoids changing the "scary" code. This often results in redundant code and redundant database calls being written. (boy i guess i work in a real hack shop!). Finally if you look at efficiency in terms of dollars the clear code is a hands down winner. Modifying the clear code will be able to be done quicker and result in less bugs.

  122. Going loopy by MROD · · Score: 1

    The only code segments you really have to worry about hand optimising are loops which happen a huge number of times.

    In scientific computing, a loop which does most of the calculation and runs hundreds of thousands or maybe millions of times is the most critical to get right. After all, one millisecond lost per loop may mean a day's extra computation time.

    A great deal of the optimisation has to be within the algorithm, making sure that you don't do unnecessary computation. However, some of it is to do with knowing how CPUs work. If you order the calculations in the correct way you can aid the compiler in its optimisation buy helping to work on data which is likely to be kept within the registers rather than flitting about and having to swap the values out to cache, or even worse, main memory.

    --

    Agrajag: "Oh no, not again!"
    1. Re:Going loopy by mihalis · · Score: 1
      The only code segments you really have to worry about hand optimising are loops which happen a huge number of times.

      Actually I have to disagree somewhat. It's easy to find a function which gets called a huge number of times, optimise the hell out of it and show that you've gotten close to the best performance for that function, and therefore assume you've gotten the best speedup you're going to get without herculean feats. However, I find it's often much easier to dig into the number of times the function gets called.

      If the function has to be called a fixed number of times (for example, once per item in a list or array) then yes, there's no room for improvement other than making the function itself more efficint.

      However a lot of code has a somewhat tangled call tree, and I find that the number of calls to some very common function is a product of multipliers in the call-chain previous.

      To give a common example - a piece of data is received that updates a table. Table elements can depend on each other, so a recalc is performed and then a redraw. Seems fine, but what if the data update was the first in a list all packaged together. Before tweaking recalc and redraw routines, you could get more bang for the buck by changing it to set a "something changed" flag for each update in the batch, and then only recalc and redraw at the end of the batch, or on a timer.

    2. Re:Going loopy by MROD · · Score: 1

      I was talking more about scientific computing where there's no redraws or user interaction. Quite often in this sort of code the act of calling a subroutine/functionother than an intrinsic one (in FORTRAN) has such a high penalty that you wouldn't do it if you could help it. Some of these codes can run for months at a time, mostly in these sorts of tight computational loops, so you can see how optimising the hell out of them can shave days off a run.

      When you're talking about GUI programming then, yes, doing intelligent redraws and updates will save huge amounts of work for the graphics system and hence speed things up. This is to do with the basc design of the code to begin with, mostly, rather than optimisation as such.

      --

      Agrajag: "Oh no, not again!"
  123. !ptr vs. ptr==NULL by SPQRDecker · · Score: 1

    As your specific example of 'if (!ptr)' vs'if (ptr==NULL)', regardless of whether or not one is more optimized than the other, there is really is little difference between the two in terms of readability, since everybody who would need to read the code would understand that. But !ptr may be a better choice for another reason: typos. A coder would be muchs less likely to mistype !ptr than he (my apologies for that last pronoun to the female Slashdot readers out there, all three of them. But I digress) than he would ptr==NULL, since more keystrokes = more opportunities to make little mistakes. As proof of that, I recently had to type in a missing NULL into the code of Nautilus' print manager because it wouldn't compile without it.

  124. The algorithm that must not be named! by coyote-san · · Score: 4, Funny

    Grrr, you named the algorithm that must not be named! Cursed be the name of the fool who thought it would be a good algorithm for introductory students - I've lost count of the number of people convinced that this satan-spawned algorithm is faster than an insertion sort (it's not) and that there's no reason for them to learn to use the qsort() function. N.B., not to implement a quick sort, but to simply call a standard library routine.

    The most frustrating thing is that, if you must use the algorithm that must not be named, the bidirectional form of the algorithm is much faster (in practice) than the unidirectional form yet really no more complex to code than the latter if you have any potential as a software developer.

    --
    For every complex problem there is an answer that is clear, simple, and wrong. -- H L Mencken
    1. Re:The algorithm that must not be named! by coyote-san · · Score: 1

      Oh yeah, the details of the bidirectional form....

      1) obviously, you go both directions.

      2) on the i-th pass, you only need to go to the N - i-th position (or the corresponding positions when headed the other way). Most people forget this nuance of the algorithm.

      3) if you're doing a bidirectional sort you can start at the last exchange. You still have to go to the N - i-th position.

      The algorithm is still O(n^2), but these simple changes will make the implementation maybe 4x faster.

      --
      For every complex problem there is an answer that is clear, simple, and wrong. -- H L Mencken
    2. Re:The algorithm that must not be named! by Anonymous Coward · · Score: 0

      Hehe.
      Heard about bogosort?
      Use random permutations and check if you have the data sorted.

      One of my friends implemented it once. It could sort arrays with as many as 14 elements in them ;)

    3. Re:The algorithm that must not be named! by Anonymous Coward · · Score: 1, Informative

      For C++, use the STL algorithms. That is all.

    4. Re:The algorithm that must not be named! by pchan- · · Score: 1

      My friend used to work at Netscape (way back when they were actually coding their own browser). He said that they discovered the reason that Netscape Navigator 3.x took so long to start up was because it performed a big bubble-sort when initializing the Java plugin. Replacing it with quicksort halved the startup time.

    5. Re:The algorithm that must not be named! by GMontag451 · · Score: 3, Funny
      Hehe. Heard about bogosort? Use random permutations and check if you have the data sorted.

      The many-worlds version of bogosort is the fastest possible sorting algorithm though. Its O(C). For those that don't know, the many-worlds version just does one random permutation, with a new universe being created for each possible outcome of the permutation. You then destroy all the universes were the dataset isn't sorted.

    6. Re:The algorithm that must not be named! by jesser · · Score: 1

      Slowsort is even better than bogosort. Read about it in Pessimal Algorithms and Simplexity Analysis (1986).

      --
      The shareholder is always right.
    7. Re:The algorithm that must not be named! by ralphclark · · Score: 1

      I managed this (bidirectional bubble sort with reducing endpoints) for my first programming exercise in my very first introductory programming class. I was just being a smartass, wanted mine to go faster than everybody else's.

      I agree it sorts the men from the boys at that very elementary level, but detecting true programming talent does require a bit more than that. Especially these days when the pool is that much larger.

    8. Re:The algorithm that must not be named! by ebyrob · · Score: 1

      Sounds *fast* but not necessarily *cheap*:

      You then destroy all the universes were the dataset isn't sorted.

      Maybe collapse is a better word here? Although this was always the part where my understanding started walking out the door... (ie: wouldn't this experientially be like rolling a couple dice and then exploding my own universe if it didn't come up boxcars?)

    9. Re:The algorithm that must not be named! by FredGray · · Score: 1

      The bubble sort (there! I said it!) is actually very efficient for the case where you know for a fact that you're starting with very-nearly-sorted data. That's the only excuse I can imagine for using it.

    10. Re:The algorithm that must not be named! by aixou · · Score: 2, Insightful

      Why not stick with insertion then? It has a run time of n on perfectly sorted data...

    11. Re:The algorithm that must not be named! by Yunzil · · Score: 1

      Grrr, you named the algorithm that must not be named!

      Let's not be prejudiced. Bubblesort is often faster than the fancier algorithms on "small" datasets.

    12. Re:The algorithm that must not be named! by Anonymous Coward · · Score: 0

      No, it is faster on datasets that start out in nearly the correct order.

      It is horrendously slow on datasets that start out in reverse order.

    13. Re:The algorithm that must not be named! by m50d · · Score: 1

      I thought it was used as an example of algorithm improvements - see, now you have the quick sort and it runs 5000 tiems as fast. If people are actually teaching that as an algorithm to be used they should be shot, of course.

      --
      I am trolling
    14. Re:The algorithm that must not be named! by TheLink · · Score: 2, Funny

      Shoot the programmer who uses bogosort.

      The programmer will be alive in the universes which bogosort worked well.

      --
    15. Re:The algorithm that must not be named! by Anonymous Coward · · Score: 0
      A many-worlds bogosort is a nifty idea, but the MWI is almost entirely rebuffed by those in the QM community.

      Here is a decent explanation:

      It seems that the majority of the opponents of the MWI reject it because, for them, introducing a very large number of worlds that we do not see is an extreme violation of Ockham's principle: "Entities are not to be multiplied beyond necessity". However, in judging physical theories one could reasonably argue that one should not multiply physical laws beyond necessity either (such a verion of Ockham's Razor has been applied in the past), and in this respect the MWI is the most economical theory. Indeed, it has all the laws of the standard quantum theory, but without the collapse postulate, the most problematic of physical laws. The MWI is also more economic than Bohmian mechanics which has in addition the ontology of the particle trajectories and the laws which give their evolution. Tipler 1986 (p. 208) has presented an effective analogy with the criticism of Copernican theory on the grounds of Ockham's razor.

      One might consider also a possible philosophical advantage of the plurality of worlds in the MWI, similar to that claimed by realists about possible worlds, such as Lewis 1986 (see the discussion of the analogy between the MWI and Lewis's theory by Skyrms 1976). However, the analogy is not complete: Lewis' theory considers all logically possible worlds, many more than all worlds incorporated in the quantum state of the Universe.

      A common criticism of the MWI stems from the fact that the formalism of quantum theory allows infinitely many ways to decompose the quantum state of the Universe into a superposition of orthogonal states. The question arises: "Why choose the particular decomposition (2) and not any other?" Since other decompositions might lead to a very different picture, the whole construction seems to lack predictive power.
      So, this leads me to conclude that the MWI bogosort, if possible, would probably not work the same way every time and this consequently suggests that O(n) or O(C) would not always be achieved.
  125. Who Cares? by krumms · · Score: 1

    "I have been coding in C for a while (10 yrs or so) and tend to use short code snippets. As a simple example, take 'if (!ptr)' instead of 'if (ptr==NULL)'. The reason someone might use the former code snippet is because they believe it would result in smaller machine code if the compiler does not do optimizations or is not smart enough to optimize the particular code snippet.

    If I were paying programmers to write code for me, and one such programmer lost sleep over such trivialities, it would be time to start looking for another programmer.

    As a programmer, unless specifically dictated otherwise by special requirements or by job title (i.e. your job title is "Pendantic Optimizer of Trivial Instructions"), your job is:

    a) Reduce complexity.
    b) Reduce complexity.

    Software is complex. You have enough to worry about without trying to determine how a compiler will optimize down to the level of a single instruction. If you're optimizing for one compiler, you're killing performance for another -there's very little to lose and so much to gain from not trying to optimize at the instruction level during the construction process.

    Yes, there is the odd exception to this rule (perhaps speed/size constraints for embedded software, off the top of my head), but man - I couldn't imagine trying to code something worthwhile and worrying about things like this with each and every key press ...

  126. IBM says let the compiler optimize by opticsguy · · Score: 2, Informative

    I recently attended a code optimization workshop for the IBM PPC compiler for Mac OSX. The compiler designer stressed that hand optimized code (i.e. unrolled loops, register variables, stupid pointer tricks etc.) only confused the optimizing compiler and would usually result in slower code overall when -O4 and higher optimizations are enabled. He provided a number of examples why this was the case and convinced us that modern compilers are much better at optimizing than humans. He also stressed the need to profile code and look for things the compiler cannot optimize. Examples are using double floats where single precision will suffice and in the case of the PPC unecessary conversions between floats and integers.

    1. Re:IBM says let the compiler optimize by clard11 · · Score: 1

      Yep. Also, the compiler can encapsulate the accumulated knowledge of the ages about the target platform. There is no way on God's earth any normal person will know enough about the instruction set of the target platform to beat that accumulated knowledge. Anyone who does should be writing compilers, not application progams. Or maybe taking up another interest in life.

      --
      catch (ModDownException mde) {post.modUp("Interesting")}
    2. Re:IBM says let the compiler optimize by sql*kitten · · Score: 0

      convinced us that modern compilers are much better at optimizing than humans

      Sure he wasn't trying to sell you a compiler?

      "That which convinces is not necessarily true; it is merely convincing" -- Nietzsche.

  127. pow by glenrm · · Score: 1

    They only thing I avoid is pow for finding a simple square of a number, better just to use x*x. Other than that write the code so you can read it 6 months from now and know what you meant.

  128. It is if... by Anonymous Coward · · Score: 0

    It is if you recognize the reference.
    Some of the source can be seen here.

  129. True, but ... by OldAndSlow · · Score: 1
    Even at the algorithm level, there is no point in optimizing before you need to. Back in my FORTRAN days, I wrote lots of bubble sorts because I could write the code in less time than it took to open an algorithm book. And 99.9% of the time bubble sort was good enough.

    Even at the algorithm level, don't optimize before you know that you have a performance/resource problem. But you better write code so clean that changing to a new algorithm isn't major surgery.

    1. Re:True, but ... by farnz · · Score: 1

      More than that; bubble sort performs very well in the case where the list is normally sorted on input (O(n) scan to confirm that the list is sorted). Depending on the properties of your original dataset, you may find that bubble sort is actually the best choice. When implementing a packet output scheduler for an MPEG system, I implemented a bubble sort, then profiled the code, as it was a potentially serious hotspot. It turned out that as the common case was rapidly repeating small packets, the scheduler was best off with a bubble sort.

  130. optimization lab in an undergraduate course by Omegalomaniac · · Score: 1

    I took a sophomore level intro to systems programming course and for one lab we had to optimize various segments of code. Problem was, the compiler knew most of the tricks the lab was trying to teach us. The compiler was already unrolling loops and using intermediate variables to avoid calculating the same value over and over again.

    The only place the compiler wasn't ideal is in optimizing code for a certain associatvity and size of cache. In other words, it's not especially worthwhile to heavily optimize code unless you know the computer architecture you're writing for very well. If you're writing multi-platform code, just forget it. Spend the time considering your choice of algorithm.

  131. Whitespace causes slow programs by Anonymous Coward · · Score: 1, Funny

    Ialwaysstripallthewhitespaceoutofmyprograms.

  132. Err on the side of readability... by Xiver · · Score: 1

    It has been my experience that it is better to write clear code, which also means clearly understandable algorithms. The vast majority of the time the compiler will optimize better than a person can anyway. If during testing it is determined that the program runs to slow, then start worrying about optimization.

    --
    10: PRINT "Everything old is new again."
    20: GOTO 10
  133. Re:clearly written code will probably perfom bette by Anonymous Coward · · Score: 0

    you do work in a hack shop! but i agree.

  134. Never trust a complier by papaver1 · · Score: 2, Informative

    I took a compliers class a year or so ago. We had to make a complier in c using lex/yacc for pascal. We also put in some optimization in it. But or profressor who has been doing this for around 10 years or so alwasy said to never trust a complier for optimizing your code. most don't do a very good job of it. and each complier optimizes stuff diffrently. some even broke code. His comparisons were using gcc, ibm complier, and a couple others, as well as optimizing in the code itself. The optimized code ran better in 90% of the runs.

  135. root of all evil is code and/or data duplication by Megasphaera+Elsdenii · · Score: 1

    Much though I admire Knuth for TAOCP and \TeX,
    I have to disagree on this one. Code duplication
    (i.e., failing to refactor and/or not abstracting
    sufficiently) and data duplication are far, far
    worse than any optimization. The only drawback
    of optimization is that it wastes time, or at
    the most clarity. I guess he himself never
    experienced any inability to abstract, which would
    explain his blindness to duplication as the
    greatest of 'harmfulnesses'

  136. That's not as funny as you think by Chemisor · · Score: 2, Insightful

    > Every programmer worth his/her salt knows that
    > source code is self documenting...

    And it's true too. Although comments are indeed a good thing, writing code that does not require them is a much better one. If your code needs comments, it's probably too complex for continued maintenance.

    1. Re:That's not as funny as you think by Osty · · Score: 1

      And it's true too. Although comments are indeed a good thing, writing code that does not require them is a much better one. If your code needs comments, it's probably too complex for continued maintenance.

      But after years and years of continued maintenance with no comments, your clean, elegant code has turned into a monster hairball of crap.

      Of course, the knife cuts both ways. If you comment everything and then the logic changes during maintenance without a corresponding change to the comments, they becomse worse than convoluted code (at least convoluted code can run through a debugger to give you an idea of what's happening).

    2. Re:That's not as funny as you think by Anonymous Coward · · Score: 0

      If your code needs comments, it's probably too complex for continued maintenance.

      This leads to me believe that you either don't code for a living, don't code on large projects, don't code on projects with other people, or haven't ever coded anything that will stay in production for longer than four years. The idea that comments are mostly redundant is extremely naive.

    3. Re:That's not as funny as you think by Rei · · Score: 1

      I think the parent is talking about doing this:

      int cycles_since_user_hit_a_key=0;

      vs:

      int cyc_key=0; //Cycles since the user his a key

      If so, I agree with them. Comments often (not always, but often) indicate that your code is getting too complex in an area, and you need to refactor and simplify it.

      --
      "Lock and load, Brides of Christ!"
    4. Re:That's not as funny as you think by Anonymous Coward · · Score: 0
      Continuing on the thought of the parent poster, here are some ways to make your code require fewer comments:
      • If your code does something 'tricksy', create a function (or macro) with a name describing the trick.
      • If notice that you're doing something nontrivial more than once, turn it into a function and give it a descriptive name.
      • If your code involves 3 or more nontrivial levels of conditional nesting, make a new function with a descriptive name to perform the work of the inner conditionals.
      • If any block contains more than one screen of code (24 lines), consider breaking it into two or more descriptive functions.
      • Avoid assignments within predicates (i.e. if, while, the 2nd expression of a for statement, the first expression of a trinary operator, and standalone uses of || and &&).
      • Avoid standalone uses of || and && (e.g. the statement "foo() && bar();" should be rewritten as "if (foo()) bar();").
      • Avoid assignments within macros (except when it is VERY clear from the name of the macro that it writes to the parameter).
      • Avoid assignments to reference parameters (see comment on macros).

      Note that the suggestion is probably the most important one. I'm going to scream the next time I see crap like "a ^= b ^= a;" manually inserted into someone's code, whether or not it has a comment.

    5. Re:That's not as funny as you think by rleibman · · Score: 2, Interesting

      Of course, the knife cuts both ways. If you comment everything and then the logic changes during maintenance without a corresponding change to the comments, they becomse worse than convoluted code (at least convoluted code can run through a debugger to give you an idea of what's happening).
      That would then be because your commented the wrong thing. Comments should have nothing to say on what is being done, that should be obvious by the code, comments have much more value, become obsolete less often and make code cleaner when they explain why things are done: comments give the big picture, the code the details. Steve McConnel's "Code Complete" is a wonderful treatise on this and other good things.
      As a trivial example:
      int a = b + 1; //Make a equal b plus one That's clearly stupid, but it's surprising how often I see code like this.

    6. Re:That's not as funny as you think by Chemisor · · Score: 1
      > This leads to me believe that you either don't
      > code for a living, don't code on large projects,
      > don't code on projects with other people, or
      > haven't ever coded anything that will stay in
      > production for longer than four years.

      Ah, here come the "I'm a badass programmer on a big project" nonsense. Here's some advice for your company:
      • Don't hire idiots. If he can't write clean, good code, that your whole team approves of, he gets the boot. Period.
      • New team members should start small. Don't give them anything important until they are familiar with the code base.
      • Do code reviews. No checkin goes in unless an experienced team member has reviewed it. This catches all those bad modifications you believe inevitable.
      • When you must write bad code, write comments. Those comments should say something like "FIXME: This is an ugly hack to quickfix bug 568132. Blah, blah." Then you must periodically go through and clean these up! Don't keep bad code around; it creates all those maintenance nightmares you believe inevitable.
      • Move your hardware and compiler targets as needed. Once all your customers are running W2k, there is no need to have those Win3.1 ifdefs and Winsock code. This is especially useful for in-house software, where you know exactly who is using it.
      • Plan to refactor regularly and make it clear to your manager that it makes the code better.
      • And, finally, do write comments where needed. If your code needs comments, it probably needs work. You can defer it, but on a large project, where you work with lots of other people, and stay in production for a long time, you must not avoid it. Otherwise you'll be constantly behind schedule, hating your job, and thinking that there is absolutely no way to make the code look good. Kinda where you are now, I'm guessing.
    7. Re:That's not as funny as you think by Chemisor · · Score: 1

      > But after years and years of continued maintenance with no
      > comments, your clean, elegant code has turned into a monster hairball of crap.

      I didn't say you should write all your code without comments. I said that it is better to write your code clearly, so it doesn't require them. If you have a hairball of crap, you obviously need comments. You should put them in when you regurgitate it. At the same time put in a reminder to yourself to fix it, like a doxygen \todo comment. Then, when the crunch period is over, you go through the code and turn it back into a clean elegant form. At that point it should once again require no comments due to painful obviousness. Finally, you should make an appointment with your supervisor to discuss crunch time policy, illustrated with graphic before-and-after printouts and estimates on just how much time you lost due to hairballs of crap in them.

    8. Re:That's not as funny as you think by Osty · · Score: 1

      I didn't say you should write all your code without comments. I said that it is better to write your code clearly, so it doesn't require them. If you have a hairball of crap, you obviously need comments. You should put them in when you regurgitate it. At the same time put in a reminder to yourself to fix it, like a doxygen \todo comment. Then, when the crunch period is over, you go through the code and turn it back into a clean elegant form. At that point it should once again require no comments due to painful obviousness. Finally, you should make an appointment with your supervisor to discuss crunch time policy, illustrated with graphic before-and-after printouts and estimates on just how much time you lost due to hairballs of crap in them.

      That's all well and good in theory, but you're making invalid assumptions.

      • You assume that you get to own your code in perpetuity, and only you get to work with code you wrote. That's rarely ever the case. You're maintaining someone else's cruft, and someone else is screwing up your nice, elegant code (because you left the company, changed jobs within the company, switched projects, whatever -- the point is, after you write the code, and perhaps after a few versions of being on the same project if you're lucky, typically you're no longer owning the code because you're off to bigger and better things).
      • "Monster hairballs of crap" don't spring up from one crunch period. They don't even spring up from a couple. They spring up from a couple years of maintenance on a code base, hacking on features (either by you because you've been given a ridiculous timeframe, or by someone else because you've moved on and they obviously don't have the proper reverance for your code), fixing bugs, adjusting to changing business rules, and so on.
      • You assume your supervisor will care when you give your little presentation about how you should never have to work anything more than 8 hour days, and preferably 6 hour days :). Chances are your supervisor is in the same boat as you, being forced from on high to agree to ridiculously short schedules while trying to shoehorn as much into each release as possible. That's not to say you shouldn't bring up your concerns, or that your supervisor can't do anything about it, just that usually your supervisor is in an even worse position than you are, and unless your supervisor is a real ass he or she already knows what you're dealing with.
      I wish I could live in a world where the only code I have to ever deal with is the code I write, and nobody ever has to modify my code. In the real world (software industry vs. academia/FOSS), that rarely happens and you have to learn how to deal with it.
    9. Re:That's not as funny as you think by Inthewire · · Score: 1

      I wish I could live in a world where the only code I have to ever deal with is the code I write.

      Agreed.

      My main job is supporting one application.
      I wrote it.
      I didn't create it, I ported the basic function and added bells-n-whistles.

      Well, the app includes TSQL sprocs used by other processes.
      No big deal, as I'm the guy who writes the sprocs.

      A few days ago someone mentions wierdness in his results.
      Cursory investigation indicates no change (diffs).

      Different symptom, same issue...dig deeper, find a subroutine has been modified.

      I suppose it's a good thing that nine people have access to the codebase.
      There's no way I would strangle eight people.
      One, two, three on a dare.
      But never eight.

      --


      Writers imply. Readers infer.
    10. Re:That's not as funny as you think by Anonymous Coward · · Score: 0

      I seriously think that good code doesn't need comments.

      Especially redundant comments like
      if (ptr=null) //let's check if ptr is null

      About maintenance though, I don't believe in such thing. Every app should be rewritten after it turns into a mess. That is, ideally, IMHO.

  137. Those are identical by iabervon · · Score: 1

    Doing the same thing for (!ptr) and (ptr == NULL) isn't an optimization; in either case, the compiler will almost certainly use a "branch if not zero" instruction. If it doesn't, it's an even chance which of the versions generates worse code.

    The only consideration is which is the clearer code, and the answer to that one is whichever is used most in the surrounding code, or, if you're just starting, whichever the programmers are most accustomed to. In this case, "(!ptr)" is more clear than "(ptr == NULL)", because it's what you've been using.

    Personally, I greatly prefer "!ptr", because I generally think about the code in terms of whether the pointer is valid. I tend to write "if (ptr) use(ptr);", and I find "if (ptr != NULL) use(ptr);" confusing, like saying, "if pointer isn't no good, ..."

  138. Leave optimization later by Anonymous Coward · · Score: 0

    I suggest you strive for clarity in your code and leave optimization later when you're done coding. This is to ensure you don't optimize prematurely and besides it usually takes a longer time to write optimized, compact code.

    The second thing is you should always try not to optimize - in other words optimize only if the performance of the program is not satisfactory. And even this should be done by locating the bottlenecks and rewrite lines to reduce overheads and cycles. You should keep in mind that you should not optimize the whole entire program.

    As for performance issues, most of the time it fallbacks to the design of the program you're coding for - the algorithm. Obviously it will do little use to optimize an unefficient algorithm, trying to squeeze every bit of speed and is no doubt slower compared to using the right one.

  139. Re:Not Machine Performance but Programmer Performa by soft_guy · · Score: 2, Insightful

    Bullshit. Some basic checks on performance are always appropriate as part of your debugging. For example, on MacOS X, I recommend you at least do two things in your app:

    1. Run top and look at the amount of CPU usage your app has during different parts of its operation. It should not, for example, run at 99% CPU usage while idle.
    2. Run QuartzDebug to make sure you aren't doing gratuituous amounts of extra drawing. Examples: redrawing more often than necessary, redrawing more area than necessary.

    And yes, for the average application, I still care about these things.

    If certain operations seem to be slow, run an optimization tool and see what "low hanging fruit" you can address.

    I've worked on several professional applications and while some of them are "weird", some level of optimization has always been important.

    --
    Avoid Missing Ball for High Score
  140. code hoisting by Anonymous Coward · · Score: 0
    The example given is pretty trivial. That's just instruction selection stuff, which is not very interesting (and easy to do). The meat of any optimizing compiler is transformations on flow graphs, which humans can help out with a little.

    The biggest problem with helping the compiler IMHO is common subexpression elimination, and code hoisting. Making sure that invariant code is only executed once is sometimes harder than it sounds, owing to the fact that, for obvious reasons, compilers must have a very conservative idea of what "invariant" means.

    Function calls are a good example, especially if the call is to a function in a different .o file. If I call sin(5) once and cache the return value, instead of every time I go through a loop, will it change the behaviour of the program? Of course the answer is "no", but telling a compiler about that can be tricky. gcc uses something like "__attribute__ ((const))" to flag a function as having no side effects (off the top of my head), but no one ever uses it (if for no other reason than it only works with gcc). If a compiler doesn't know that a function has no side effects, it's not going to optimize around it very well :(

    My advice for programmers worried about speed is to be const-correct wherever possible, and to bring computations outside of loops whenever possible. Other than that, I can't think of anything that a compiler can't do infinity times better than all the world's humans put together.

  141. You should not optimize by Wannabe+Code+Monkey · · Score: 1

    I've gone to a few seminars on compilers and compiler optimizations and it's really amazing how well compilers do in regard to optimizations. You'll often also find that the place where you think there are bottle-necks are really not most critical part of the code. This point was discussed in "Refactoring: Improving the Design of Existing Code" by Martin Fowler. His advice is to write code for yourself and for other coders and such. Only after you have something that works and has nice clean code should you think about optimizations. Refactoring will often make it easier to optimize later if you need it.

    I also think it may be possible to defeat your compilers optimization techniques by trying to optimize yourself. I'm not a compiler person and only have had one experience to lead me to think this. But for an algorithms class we were discussing the advantages of using sentinel values when sorting data, something about being able to eliminate the check for whether the current index is past the end of the array for each iteration. Anyway we actually had to write two different implementations of this sorting algorithm in C and mine was actually slower in the sentinel value version. The only explanation I could think of was that there were some optimizations going on which relied on the loop being of a form, and changing it around caused it to loose this optimization.

    --
    We always knew Comcast was corrupt, here's the proof: http://tech.slashdot.org/comments.pl?sid=1909890&cid=34545432
  142. Most people aren't framing this properly. by Elwood+P+Dowd · · Score: 1

    Everyone is just saying, "don't optimize a line of code, optimize your damn algorithm," which is dead on.

    However, the guy is still asking a *somewhat* valid question. His mistake is in optimizing prematurely. After his code is correct, if there are reasons that it would be better if it were faster, he should optimize his algorithms. After he optimizes his algorithms, if there are still reasons that the code needs to run faster, then he should try single line optimizations like the one he describes on the bottleneck inner loops. Check the results with a stopwatch. You don't have to know the first thing about the state of the art in compiler optimizations.

    Maybe he's found a situation where less readable, hinky code is worthwhile. You only find that out after you've discovered a performance problem.

    The remaining interesting question is, what is the state of the art in compiler optimizations. I haven't a fucking clue. And I don't know whether it's better or worse in embedded systems. I code database GUIs in VB for a living. You can optimize my code when you pry it from the runtime's cold, dead hands.

    I played around with sun's cc optimizations in my compiler course in college, and it did a pretty good job of sniping the low-hanging fruit, like unused branches & loops & etc. Since I was not (am not?) much of a programmer, I couldn't imagine what the challenging aspects of optimization would be, so I couldn't poke around.

    I guess the general rule is that you should use the chip vendor's compiler, right? Intel's compiler has always been faster than gcc and VS C/C++ in the past, and IBM's stuff certainly beat the pants off gcc for POWER/PPC. And Sun's cc was oodles better than gcc in my little toy tests in college four years ago.

    --

    There are no trails. There are no trees out here.
    1. Re:Most people aren't framing this properly. by Capt_Troy · · Score: 1

      Your post makes me think about a guy with a sore thumb trying to time a snippet of code with a stopwatch.

      CLICK! damn.
      CLICK! damn.
      CLICK! damn.

    2. Re:Most people aren't framing this properly. by MBraynard · · Score: 1
      Hey There -

      You do the referral in my sig and I will do yours - just shoot me an email when you have done it at mattatbraynarddotcom.

      I already got the Ipod and Xbox free. Good luck.

    3. Re:Most people aren't framing this properly. by Poeir · · Score: 1

      Why use a stopwatch? On Unix (well, Linux, anyway), there's a command time which tells you how long a program takes to run. Stick the original subroutine in a 10000 loop in main, time it, then run the new one 10000 times. If it's faster, great. Try to use random data with an O(1) generation time; otherwise, it might be that that particular combination of data happens to be faster.

      --
      Sigs are like bumper stickers.
  143. Abortion? by Anonymous Coward · · Score: 0

    if (0!=ptr) is a hideous abortion, because it's not readable

    My, my, but aren't you the wordsmith...

    You maybe meant aberration or abhorable? Abortion means the premature end of something, in today's society most likely the premature end of a pregnancy. In any case, if (0 != ptr) is perfectly readable for anyone who's written more than a simple "Hello World" routine.

  144. ANSI C by bAdministrator · · Score: 2, Informative

    ANSI C: "The macro NULL is defined in <stddef.h> (and other headers) as a null pointer constant."

    The definition of a null pointer constant: "An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant."

    Source: Programming languages - C (ISO/IEC 9899:1999)
  145. Make your code clear. by Phreakiture · · Score: 1

    Make your code clear, never mind a cycle here or there during compile time or run time. Chances are that the optimizer will squeeze quite a bit out of it, but even if it does not, except in some rare and/or degenerate cases, the computer your code will be running on will probably be so extremely overpowered for the task that you won't notice the difference.

    However, in comparison, the amount of time saved by the code being clear to the next programmer to view it will be invaluable.

    Also, please consider your algorithm carefully. Make sure that it isn't spinning its wheels a lot, else your (!ptr) vs (ptr==NULL) really isn't going to make a lot of difference.

    Of course, it goes without saying that you can ignore my comments if you are entering the Obfuscated C Contest. :-)

    --
    www.wavefront-av.com
  146. Re:.NET Has An *Easy* Way for Compiler Optimizatio by TheRaven64 · · Score: 1

    Almost any other platform has exactly the same ability. GCC lets you inspect the assembly, and gdb (as I recall) allows you to view the disassembly for any given line while debugging.

    --
    I am TheRaven on Soylent News
  147. Optimization? by Anonymous Coward · · Score: 0

    With all the bloated code out there, I'm suprised that anybody is even concerned about optimization. The original poster must be the only programmer left that even bothers to think about optimization...

  148. Program human readable by John+Bokma · · Score: 1

    If it doesn't work fast enough it's often cheaper to buy faster hardware.

  149. Re:Clear Code - Boeing by Anonymous Coward · · Score: 0

    Boeing qa testing requires that each and every machine instruction be executed at least once for the embedded systems in their aircraft.

    So if (a != 0) || (b != 0) does not get short circuited in testing.

  150. Compilers suck by Zombie · · Score: 1
    I'm a professional embedded developer. I agree with other posters warning about premature optimisation, and the trade-off between legibility and maintainability vs. performance.

    Now, when it comes to optimising your bottlenecks at the end, take into account that compilers really sucks at optimising. Badly. Last week, I was debugging this line of code:

    a /= 4;

    I had to come to the horrible conclusion that the compiler had taken this integer division and made it into a library call to the divide function. Solution:

    a >>= 2;

    I write my code legibly. I test and debug until it is correct. Then I look at the generated assembler (objdump -DS is your friend). Then I rewrite my C code until the compiler generates somewhat decent machine code.

  151. (!done) by pyrrho · · Score: 1

    I have always liked while(!done)... that reads to me... "while not done" and seems really clear to me that somewhere in that clause will be ways of setting done=true.

    I've had that corrected by respected colleagues to "while (done == false)" ... is that really any more clear?

    I remember when the if (!ptr) thing looks confusing, so I understand, but I had been programming only a couple months at the time, quite long ago, and is it bad for that to make sense? Don't get me wrong, obviously this is different from my while example because strictly speaking, NULL does not have to equate to "false"... it just happens to on about every architecture made. The "while" version is more defensible, because !done really is the same as (done == false), even if false is not (int)0.

    --

    -pyrrho

    1. Re:(!done) by cakoose · · Score: 1
      I've had that corrected by respected colleagues to "while (done == false)" ... is that really any more clear?

      One possible reason to avoid "(!ptr)" is because you're mixing pointer and boolean types. The "!" operator is a primarily a boolean operator and so there's nothing wrong with using it on a boolean variable. I wonder if your colleagues would apply the same rule to "true":

      while (running == true) { ... }
      if (button.IsPressed() == true) { ... }

      In fact, you might get yourself into a little trouble by comparing to "true". Since, in C, a false value is a value that is non-zero, comparing to some constant "true" wouldn't work pefectly all the time.

  152. Complexity: It's not the code, it's the CPUs by yppiz · · Score: 1
    Compilers often cannot optimize even simple code for a given architecture, because the architecture itself and its rules for execution are complex. For instance, depending on what tricks you use, running the Stream benchmark on an Opteron can run at 1.5GB/s assuming correct code and alignment, but no compiler flags, 2.2GB/s with the "obvious" flags on gcc (-O3 -m64), and over 3GB/s with the Portland Group's pgcc and using multiple arcane flags.

    Even a simple sequential read loop that exceeds the L1 cache can benefit greatly from the appropriate cache hints in the assembly (prefetchnta and its variants).

    Toss in a second processor and a NUMA architecture, and everything gets even more fun.

    For examples of the hacks you can do on Opterons that vastly improve simple C code speed, take a look at the stream.c source and see AMD's technical pubs no. 25112, 24592, and 32035.

    --Pat / zippy@cs.brandeis.edu

  153. clarity is in the eye of the beholder by idlake · · Score: 1

    The reason someone might use the former code snippet is because they believe it would result in smaller machine code

    Anybody who uses "if(!ptr)" because he thinks it generates better code these days should be banned from programming in C (but then, we probably should just ban C programming altogether).

    IMHO the latter code snippet is clearer than the former

    I think there is a good chance that you don't actually understand what "if(ptr==NULL)" means. For example, if "ptr" is of type "int", can you answer the question of whether the compiler will give you a type error?

    Ultimately, no amount of macro magic (like NULL) is going to fix C's pointer system, so one might as well go with the most portable expressions. It's an unfortunately fact that NULL has often been defined inconsistently (in fact, there are half a dozen different definitions scattered through dozens of Linux header files), so I avoid it in my code. Any C programmer worth his salt should have no problem with "if(!ptr)" or "ptr = 0", and those will work consistently on just about any C compiler in existence, no matter how old. It's unfortunate that it looks obscure to the uninitiated, but, hey, that's C for you, and in this case, I think the cure is worse than the disease.

  154. If you're not willing to TIME it... by dpbsmith · · Score: 4, Insightful

    ...then the code isn't important enough to optimize. Plain and simple.

    Never try to optimize anything unless you have measured the speed of the code before optimizing and have measured it again after optimizing.

    Optimized code is almost always harder to understand, contains more possible code paths, and more likely to contain bugs than the most straightforward code. It's only worth it if it's really faster...

    And you simply cannot tell whether it's faster unless you actually time it. It's absolutely mindboggling how often a change you are certain will speed up the code has no effect, or a truly negligible effect, or slows it down.

    This has always been true. In these days of heavily optimized compilers and complex CPUs that are doing branch prediction and God knows what all, it is truer than ever. You cannot tell whether code is fast just by glancing at it. Well, maybe there are processor gurus who can accurately visualize the exact flow of all the bits through the pipeline, but I'm certainly not one of them.

    A corollary is that since the optimized code is almost always trickier, harder to understand, and often contains more logic paths than the most straightforward code, you shouldn't optimize unless you are committed to spending the time to write a careful unit-test fixture that exercises everything tricky you've done, and write good comments in the code.

    1. Re:If you're not willing to TIME it... by owlstead · · Score: 1

      You cannot know which code is faster on a processor by looking at it... all too true.

      And the problem is that you don't know what is going to happen with the next great CPU that comes along. Changing the entire codebase to optimize for that CPU (and, in the worst case, branching that piece of code in your versioning system) is much harder then choosing a CPU from the drop down box in your favourite IDE.

      In other words, in this world you do not write code specific for a CPU or even a system architecture. Unless you are in a market that requires you to do so, like embedded systems. And don't forget that even then the processor probably runs 10's of MHz or more with no OS overhead.

      Now, creating a good design...that helps.

    2. Re:If you're not willing to TIME it... by mystran · · Score: 2, Interesting
      Actually, while I agree on the main point, I must disagree to a certain degree, because my empirical experience suggests something different: If something looks complicated, there's a good chance that by trying to write it in a more clear/straightforward (so as to make it easier to understand) will also result in more efficient machine code (as benchmarked).

      As such, I'd say: if something is too slow, benchmark it, then try to write a more simple version and benchmark that. Many times the result will be faster (and rest of the time you probably need a better algorithm).

      As funny as it sounds, because compilers do fancy optimizations, writing code to "explain the logic to the compiler" might well enable optimizations that a compiler couldn't use on "more optimized" code. One obvious (and simple) example is the "const"-modifier in C, which helps clarify extent of usage to both other programmers AND the compiler; the result in performance can be quite dramatic in truly CPU-bound code.

      --
      Software should be free as in speech, but if we also get some free beer, all the better.
    3. Re:If you're not willing to TIME it... by Kiryat+Malachi · · Score: 1

      Embedded sometimes does have OS overhead, for the record.

      That said, we still do *not* write processor-specific code for the main program, unless we absolutely have to. Any processor-specific init code is shunted into a seperate init file. For a lot of projects, it winds up being cheaper to just pay a couple extra cents per chip in order to not have to pay the programmers a ton of money to optimize. Maybe if you're working on a 5c processor you have to, but that's increasingly rare these days.

      --

      ---
      Mod me down, you fucking twits. Go ahead. I dare you.
      (I read with sigs off.)
  155. (correction) by coyote-san · · Score: 1

    Oops - forget about that last point. I was thinking about an unrelated algorithm. This is why I always code from CLR, complete with assertions and page references in the comments. It doesn't matter if the algorithm is fast if it's also wrong.

    --
    For every complex problem there is an answer that is clear, simple, and wrong. -- H L Mencken
  156. Know your data structures.... by robbo · · Score: 1

    I have to confess that I'm guilty of this too, but you'll gain much greater speedup out of your code when you understand your data structures.

    Classic example-- in the middle of a loop, calling size() on std::list<T>. (for the ignorant, that's typically O(n), although I suspect the ISO standard simply doesn't guarantee that it's constant time). I'll abuse it simply because I'm lazy, but it makes me cringe every time I see it in otherwise well-written code.

    --
    So long, and thanks for all the Phish
  157. Shorter example is clearer by defile · · Score: 1

    When I read

    if (!ptr)

    in my head I think "if not pointer" which I interpret as not pointing to anything. When I read

    if (ptr==NULL)

    in my head I think "if pointer equals null" which I interpret the same way. As a result, I end up writing the former because it consumes less ocular and mental bandwidth.

  158. My experience by pclminion · · Score: 3, Insightful
    First, let me say what sort of code I write. I work almost exclusively with high-performance, 2D graphics code. Most of what I do involve manipulating bits, worrying about cache utilization, and squeezing the last bits of performance out of a three line inner loop. I'm just going to rattle off what I know from my experience with gcc and VC++:

    The compiler will perform strength reduction in all reasonable instances.
    The compiler will raise invariant computations from inner loops in almost all cases that do not involve pointers.
    The compiler knows how to optimize integer division in ways I wouldn't have even thought of.
    The compiler sometimes "forgets" about a register and produces sub-optimal code for inner loops.
    The compiler can't always tell what variable is most important to keep in a register in an inner loop.

    Other stuff:

    x^=y; y^=x; x^=y; optimizes to an XCHG instruction with gcc on x86. I was amazed that it could do that. (Yes, that piece of code exchanges x and y). On the other hand, tmp=x; x=y; y=tmp; doesn't get optimized to an XCHG. Obviously, the compiler is using a Boolean simplifier or identity-prover.

    The compiler always assumes a branch will be taken (unless you use certain compiler switches to change this behavior). Thus you should always arrange your conditional tests so that the less-often executed code is within the braces.

    Don't be afraid to write complex expressions. Subexpression elimination is almost foolproof in all instances where pointers are NOT involved. It's better to leave your code clear, and let the compiler optimize it.

    And ABOVE ALL:

    No matter how much the compiler optimizes your code, you can throw it all down the toilet with bad design by screwing the cache utilization. This is EXTREMELY important especially in graphical applications which process huge raster buffers. Row-wise processing is always more efficient than column-wise. Random access will kill your performance. Do not trust the memory allocator to keep your allocations together. Write your own allocator if you are dealing with thousands or millions of small, related chunks of information.

    I could go on... But I must also second what others have said, which is to perform algorithmic optimizations FIRST and do not bother with constant-factor optimizations until you are CERTAIN that you are using the best algorithm. If you ignore this advice you might waste a week optimizing a three-line inner loop and then come up with a better algorithm the next week which makes all your hard work redundant.

  159. Yes and No by WindBourne · · Score: 1

    First off, !ptr is easy to read for any C coder. In addition, in an embedded system, speed and/or size may matter more.

    But with that said, I agree with you on general systems. In this day and age, even for MOST embedded systems, memory and cpu power is cheap enough, that code maintence becomes a costly issue.

    --
    I prefer the "u" in honour as it seems to be missing these days.
    1. Re:Yes and No by kwiqsilver · · Score: 1
      !ptr was his example of a simple case. I wasn't saying it's too complex to read. But
      if (ptr == 0)
      does look "cleaner". And as somebody mentioned above
      if (0 == ptr)
      looks cleaner and makes equality test versus assignment operator errors show up at compile time.

      I was also speaking in terms of non-embedded systems, where storage and CPU time are plentiful. In an embedded or real-time environment, it might be more cost effective to tweak the code.
  160. pedantic code is NOT more readable by jlusk4 · · Score: 1
    One thing I hate is stumbling over someone's wordy, pedantic code when I could just as easily read something more... algebraic.

    We've got a guy here who seems to think it necessary to write conditionals like this:

    while (doneProcessing != true) {
    ...
    }

    Drives me nuts. What the hell is wrong with just

    while ( ! doneProcessing) {...
    ??

    John.

    1. Re:pedantic code is NOT more readable by taradfong · · Score: 1
      Yeah, me too. And you know what drives me nuts are people that do...
      while (!doneProcessing) {
      ...instead of...
      while (!done) {

      'Processing' is redundant. What else would a computer be doing?
      --
      Does it hurt to hear them lying? Was this the only world you had?
    2. Re:pedantic code is NOT more readable by jlusk4 · · Score: 1
      It's generic code. I picked a generic English phrase. Gimme a break.
      while(!d){...}
      better?

      how about:
      #define i while(!d)
      :
      :
      i{..}
      >:(

      As simple as necessary, but no more. "Done" is too generic. Done what?
      while (!done1){
      while (!done2) {
      ...
      }
      }
      John.
    3. Re:pedantic code is NOT more readable by Anonymous Coward · · Score: 0

      He probably says the same about yours. Unless you have a coding standard either is valid.

      Get off your high horse.

  161. Save the tweaking for Critical code by DCheesi · · Score: 1

    Probably 95% of your code doesn't even need optimization. I program for embedded devices with real-time functionality, but even so I've rarely had to optimize anything other than Interrupt Service Routines and similar Critical Section code. Most normal code in a modern application will have plenty of time to run no matter how sloppy it is. It takes a lot of inefficiency before things bog down.

  162. Constants first!!! by BobGregg · · Score: 1

    >>As a simple example, take 'if (!ptr)' instead of 'if (ptr==NULL)'.
    >>...
    >>IMHO the latter code snippet is clearer than the former, and I would use it

    Please, PLEASE tell me you wouldn't use "ptr==NULL". For Pete's sake, tell me you would use "NULL==ptr" instead. Forget optimizations - the first "intermediate" thing you learn in C++ is to ALWAYS put the constant first in equality comparisons so that in case you accidentally use only one "=" some day when you haven't had enough caffeine, the compiler will catch it for you.

    It doesn't matter how fast your code runs if it isn't correct. One should almost always prefer a correctness tradeoff over a performance tradeoff.

    1. Re:Constants first!!! by fgb · · Score: 1

      I have to strongly disagree with this. This advice probably made sense at one time, but there is no longer any reason to sacrifice code readability in this manner. Any modern C/C++ compiler will (by default or with the appropriate option set) flag statements such as:

      if (x = 0)

      with a warning. If you did intend to perform an assignment, the correct way to write it would be:

      if ((x = n) != 0)

      or better yet:

      x = n;
      if (x != 0)

      but please, can we leave hideous constructions like if (0 == x) in the past? They no longer serve any purpose except to cause some cognative dissonance to anyone reading the code. (how could the value of 0 change?)

    2. Re:Constants first!!! by z4ce · · Score: 1

      Not only that but its not the way the lauguage is written. Let's say x is an object and you've overloaded the == operator. x == 0 would use the operator== function on x. 0 == x would not. If someone was writing c++ using if (0 == x) they deserved to be thwacked with a large trout.

    3. Re:Constants first!!! by Anonymous Coward · · Score: 0

      Not only that but its not the way the lauguage is written. Let's say x is an object and you've overloaded the == operator. x == 0 would use the operator== function on x. 0 == x would not. If someone was writing c++ using if (0 == x) they deserved to be thwacked with a large trout.

      That's only true if they provided

      bool X::operator==(int i) const {/**/}

      or

      bool operator==(const X& x, int i) {/**/}

      and forgot to also provide

      inline bool operator==(int i, const X& x) {
      return x == i;
      }

      For symmetry purposes, both should be provided.

  163. Suspicious Comments by deangelo · · Score: 1

    I find most of these comments about writing "slower" clean code, to be suspicious at best, in my experience (10 years of c++, Bsc CPSC, MSC CPSC in progress, contracting, coop ... you get the idea) cleaner well written code dosn't perform significantly worse than highly hand tuned code. Humans just arn't good at deciding when certain optimizations should be employed, like unrolling loops, inlining, placing certain vars in registers ...

    The comments about premature optimizaion, and profiling are bang on.

    The only time I resort to hand optimizations now is in embedded microcontroller applications where there are significant hard limits, like memory, and stack and code space. Some of the microcontrollers I use only have 256 bytes of ram, 4 levels of stack, a couple of k of program memory, and run at about 1mhz, so optimizations are justified but other than that don't waist everybodies time.

    deAngelo

  164. Some Thought by nate+nice · · Score: 1

    If programming in C, as your examples have shown, use the "register" keyword in parts you're not sure will be optimized by the compiler all too well. Examples of this are blocks that use numerous variables, some of which are referenced more than others, blocks that make many function calls, so the compiler knows not to send everything to memory before loading the new frame in and in situations where it would appear a variable won't be used for awhile but you know the function coming next is going to want to manipulate it. Luckily, most compilers have good enough optimization that using "register" ins't as valuable as it once was. Just make sure that when you use it, don't set all variable to "register" because that defeats the purpose. Just the ones you know will be referenced a lot.

    Another obvious clue is use effeciant data structures and algorithms. Plan your code before you write it and try and prove your algorithm is running in the fastest possible time.

    Also, to get an idea of what most modern compilers do to optimize, and thus allowing you to see if what you hav written is not going to get optimized, read the Dragon Book, or at least the last few parts where this is discussed. What is said there still to this day are some of the most common techniques to optimize code. If you give this some time you will be able to analize what part of your code won't get optimized well.

    As for your example, both conditional statements you provided would most likely get the same asm code generated. Probably along the lines of a beqz (branch if equal to zero) statement or an equivalent. Your statements are both boolean and comparing a variable to a constant, 0. Semantic analizers would pick up on this immediatly.

    Also, in C don't ever pass by value but that should be obvious to anyone getting paid to code in C.

    Lastly, if a part of your code doesn't seem optimal, it's probably a function of your poor algorithm and not that of the compilers code generation. I would doubt you will write a better asm program than your compiler would. Write a new algorithm and use tools to inspect your bottlenecks, like many others have pointed out.

    --
    "If you are a dreamer, a wisher, a liar, A hope-er, a pray-er, a magic bean buyer ..."
  165. As an embedded device driver developer.... by Ghengis · · Score: 1

    As an embedded device driver developer, I tend to err on the side of the compiler NOT being smart. In most cases, the compiler is smart enough to do the right thing. Many times, it optimizes different ways of writing the code into the same machine code, however, there have been instances when the compiler I've been *forced* to use didn't do this. For this reason I always leave the decision to myself and not the compiler. This also means knowing enough about how the particular compiler does things to make the informed decision. For desktop / user-level developers, however, this probably isn't necessary.

    --

    "The best laid plans of mice and men gang oft agley..." - ROBERT BURNS

  166. Programming Practice by jevvim · · Score: 1
    I was always taught that it was bad form to depend on
    if ( !ptr )
    being correct as a NULL-pointer test. Not that it's a violation of the C standard, but it's converting a pointer type to a boolean type, which is a bad habit - especially in a permissive language such as C.
  167. exactly! by pyrrho · · Score: 2, Insightful

    comments can be misleading, but the code never lies, it always works exactly as written.

    --

    -pyrrho

    1. Re:exactly! by Inthewire · · Score: 1

      ...according to che compiler / VM / etc.

      --


      Writers imply. Readers infer.
  168. Abelson & Sussman's SICP by jeddak · · Score: 1

    "...programs must be written for people to read, and only incidentally for machines to execute."

    Clarity first. And assume the compiler knows what it's doing.

    Google "literate programming" for more supporting material.

  169. Re:root of all evil is code and/or data duplicatio by StillNeedMoreCoffee · · Score: 1

    Actually I think that some small local optimizations that are done by programmers prevent the compiler from being able to do deeper and more fundemental optimizations.

    The point being that the programmer should write clear understandable, readable, maintainable code and let the compiler do the optimizations. Its its job. If your compiler is not doing a good job then get another compiler.

    A good example in point is the Fortran compilers these days because of their more restrictive structure and good optimizations benchmark at 20 times faster than the equivalent C or C++ code of the same algorthims. And not hand optimizations will catch that up. Check it out, for heavy numerical and array processing use Fortran. Not because of the language but because with the language and a good optimizing compiler, magic happens.

  170. TechTV? by djplurvert · · Score: 1
    Slashdot reminds me more and more of techTV.

    "Ask slashdot elementary facts about programing in C."

    As several readers have already pointed out, not only does the author not grasp the basics of C but he doesn't really understand what good optimization is all about. Why does this qualify as "news for nerds"? There are plenty of good sites that discuss this topic in general. Here are a couple from the FIRST PAGE of a google search

    Optimizing for embedded systems

    From the dsp perspective

    paper from a professional on the subject

    That last paper begins with this sage advice


    The single most effective optimization technique is to use a profiler to identify performance bottlenecks. It's often difficult to guess what part of your program is consuming the most resources, and if you base your optimization efforts on speculation instead of real data, you'll waste a lot of time speeding up the parts of your program that were fast already.


    All of that found in ONE google search on the FIRST page and I'm QUITE SURE it took far less time than submitting a "story" to slashdot.

    Here's a hint editors. Take a lameass story like this and turn it into something worth discussing.

    Instead of letting someone ask "what's the difference between these two things that are clearly the same to any experienced programmer", how about rephrasing that to one or more of the following questions which are more general and might trigger LESS inane banter.

    What kinds of low level optimizations do C compilers do for you automatically and what kinds of things are they unable to determine?

    Under what conditions is it worthwhile to hand optimize C code and are there situations where writing assembler is necessary or recommended?

    What specific profiling techniqes do you use to determine where your code is spending its time and what kind of gains can you expect to receive by tweaking the existing code vs rewriting it in a different algorithm?

    In what ways do you apply the 90/10 rule when developing and optimizing code?


    ymmv.
    1. Re:TechTV? by cakoose · · Score: 1
      What kinds of low level optimizations do C compilers do for you automatically and what kinds of things are they unable to determine?

      This is actually what I thought the story would be about. I think that the form of the question was reasonably clear to anyone who wasn't desperate to impress others with newly-acquired-but-only-tangentially-related information. Too bad most of the responses were just smug and condescending. "Instead of answering your questions, I'll just suggest that you don't really need to optimize." The worst part is that they all said the same exact thing, drowning a potentially interesting Slashdot topic in noise.

      I agree that the submitter does sound a little naive, but hey...before learning some assembly and computer architecture, so was I. I used to think that the speed of my code was rougly proportional to the number of logical operations in my Pascal source code (though I'd like to think I never worried about the difference between "!ptr" vs "ptr==NULL").

  171. Rules for optimization by CSMastermind · · Score: 1

    Normal Programmers:
    Don't do it

    Expert Programmers:
    Don't Do It

    Unless it's requested but the user.

  172. My cents by Anonymous Coward · · Score: 0

    Nobody will most likely read it but I type this anyway.

    About 100% of real and bad performance problems I've seen this far has been design problems and the algorithm selection problems. And most often the former one is the real problem. We can make plenty of code, but our design usually isn't made for performance. One single bad way to handle SQL queries can sink the whole software to the deep dungeons of bad performance. One single SQL scheme design desicion can throw us to middle of the deep sea of bad performance.

    And to the orginal q... at C++ if (!ptr) is suggested. It's more portable than if(ptr != NULL)

  173. Optimization rules... by Anonymous Coward · · Score: 5, Funny

    When I wrote my ray-tracer for the final project of my graphics class, I used gcc -o3 and it optimized my code into Pov-ray, which was sweet. I was done with the project in like ten minutes.

    Plus I got extra credit for implementing phong shading. I didn't even try to do phong shading.

    1. Re:Optimization rules... by hesiod · · Score: 0, Troll

      Don't take this the wrong way, but it doesn't sound like you "wrote" a ray tracer at all. You slapped a front end on an existing one, no?

      Granted, there may be subtle differences I'm unaware of because I've never used it...

    2. Re:Optimization rules... by mkavanagh2 · · Score: 1

      I think it was humour :)

    3. Re:Optimization rules... by gardyloo · · Score: 3, Funny

      It's OK -- the great-grandparent poster optimized his humour code a little *too* much. Now we have to work on interpreters for /. readers...

    4. Re:Optimization rules... by MemoryAid · · Score: 1
      The best humorist is the one who can trigger a laugh in any one of several people standing in a group, without the others knowing why he laughed.

      In this example, I was one of the others.

      --
      Language students: Don't try to learn English here. This ain't it.
    5. Re:Optimization rules... by hesiod · · Score: 1

      I'd like to meet the dumb motherfucker that modded me troll so I can use my new LART. GET A FUCKING CLUE, IDIOT.

  174. Bullshit by Anonymous Coward · · Score: 0

    Every C-programmer (who earns the title) knows that if(!ptr) and if(ptr == NULL) give the same code. But many find the former just as readable if not more. Just look at the kernel sources.

    I highly doubt the submitter really does C for 10 years.

  175. what compiler? by ohsoportly · · Score: 1

    As a DSP firmware developer the only code I can rely on is the code I generate myself. For most signal processing applications, speed is the most important objective and sacrificing readability (which can be remedied with good comments) is well worth a few extra cycles. You really can't trust a high level language compiler to always pick the best method for a particular task.

  176. Experience shows me... by gr8_phk · · Score: 1
    You must do some profiling. Most people on slashdot have never done what I consider embedded code (PC 104 boards don't count). I write for micro controllers and DSPs, and the compilers vary a LOT. Even compilers from the same vendor with different target achitectures can have different optimization capability. When I do write a really strange looking expression, I often leave the equivalent readable code commented out or give a good description of what I did for whoever works on it next.

    From the sound of your post, I'm assuming you already understand the bit about premature optimization and are now at the point where you must do it anyway. Slashdot is probably not the best forum for this, as they all have great hardware and compilers and wouldn't understand how someone could actually care about saving 1/2 microsecond of execution time on a 60MHz machine.

    My last round of optimization was in a complex control loop running in a 20KHz interrupt on a 60 MHz part. This code was eating about half the available processor time, and reducing it by a few microseconds freed enough time to add 15 percent to the background code - which is quite substantial. It was a series of 13 different improvements slightly more complex than the example you gave. I don't recommend doing this stuff all over the place, but when you need to the only way to be sure is to do real timing tests - sometimes things you think will help don't and things you think are the same are better... And it mostly depends on the compiler you've got.

  177. They are equivalent by Ulrich+Hobelmann · · Score: 0

    !foo means just: foo == 0, and the compiler has to check the value anyway, since most CPU architectures can only branch on a flag in the condition register.

    Don't worry, just use whatever is clear. I prefer "if (!foo) error", but that is a matter of taste. Just be consistent. ;)

  178. Applies to language too by Anonymous Coward · · Score: 0

    That quote applies to what language you chose to write in as well. Tight VNC's Java client is actually faster than the (windows) native client... it's nearly twice as fast at playing movies at least. Smalltalk's GUIs are indistinguishable from native GUI's even though they are painting their own components because their painting code is elegant and sweet -- that's despite the best smalltalk being 4x slower than Java, which is around 1.5x C. Of course, you don't want to do math in Python, but even though Python is on the order of ~100x slower than C at math it's still useful for a LOT of programs.

    These languages let you easily use the right algorithm. There have been countless times in C where is was just too much damned trouble to use the right algorithm (would take 20 lines of customized code instead of one-line method call) or do the proper checks. As far as I am concerned the ONLY reason to program in C is if you MUST HAVE excellent performance. Otherwise it's just a waste.

  179. Re:Clear Code [follow the parent link] by Anonymous Coward · · Score: 0

    That is quite an awe-inspiring read. Thank you.

  180. Having done YEARS of perf work by melted · · Score: 1

    Here's what I have to say on the topic:
    1. Do not optimize _code_, optimize _algorithms_ , architectures and SQL schemas, and do so only in the case when you're 100% clear that there will be a sizable benefit.
    2. If you do #1, don't do any optimizations until you've done at least preliminary perf testing and identified the bottlenecks. It's important for perf test to mimic real workload as close as possibly. Half-assed test scenarios are about as good as no testing, and sometimes worse because they give you the false sense of confidence, when in fact you should have none.
    3. If you're making changes in an existing product, measure improvements under _varied_ workloads. Collect and study the trend data.
    4. Don't optimize stuff which does not get called/accessed often or where you know the benefits of optimization will be minuscule. I've seen some programmers optimize error logging to avoid a fucking _function call_ (for some reason they thought it was expensive) and then turn around and do horrible performance decisions in SQL schema.
    5. Don't optimize without first talking to your perf/stress person (if you have one). If you don't have a perf/stress guy, hire one. Some developers think they know a lot about perf and optimization, while in fact all they know are urban legends. So they spend a bunch of time on urban legends, and the real perf issues remain in the product. Your perf guy, if he's good, KNOWS what's broken and how to fix it. Listen to what he has to say a little more.
    6. Pay the most attention to shared resources and threading issues around that. In this day and age, processors are blazingly fast, so the most common source of perf problems is locking on a shared resource. Do code reviews on code that's heavily multithreaded and employs a lot of locking. If you use MS SQL server, run Index Optimizer and see what it has to say. Also, run Microsoft PSS "Blocker" script under a real world workload to see if you're having locking issues.

  181. Quotes from those older & wiser than me by dmccarty · · Score: 1
    Quoting Jack Ganssle, who quoted Brian Kernighan:

    Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.

    --
    Have fun: Join D.N.A. (National Dyslexics Association)
  182. Also by geekoid · · Score: 1

    be sure that level of optimization is really needed.

    I can't tell you how many times I found a developer 'optimizing' code to save a millisecond..for a desktop application.

    If you are pulling data drom a database, optimizing the call in a manner that save 1 second isn't worth the effort.

    Of course, the story mentions C, so I assume this person is writting low level code.

    --
    The Kruger Dunning explains most post on /. http://en.wikipedia.org/wiki/Dunning%E2%80%93Kruger_effect
  183. "cc -S" is your friend by Detritus · · Score: 1

    If you're writing performance critical code, or just using a new compiler or target, it can be educational to look at the output of "cc -S". Does the assembly code match what you intended to do? Is the optimizer doing stupid things, possibly because of language rules and the way you wrote the code? Sometimes you can learn things about the target architecture by seeing examples of architecture dependent "tricks" in the generated code. The programmer who wrote the code generator probably knows a lot more than you about what is optimal for the target.

    --
    Mea navis aericumbens anguillis abundat
  184. Optimize your compiler by Ingolfke · · Score: 1

    I ask the Slashdot crowd, what they believe the compiler can be trusted to optimize and what must be hand optimized?"

    This question needs be considered, because the poster is staring right at the answer and is still missing it. You can write code. You have a compiler. OPTOMIZE THE COMPILER. That's the beauty of open source. Pry open the insides of GCC and tweak it so that it optimizes your code better. If you're a decent programmer, submit the idea back to the community. For some reaon people don't seem to remember that your compiler is just software too, it's not sacred, optimize to your hearts content. I don't know if this is because people are too used to closed source compilers or very high level programminging languages like Python and Ruby.

    1. Re:Optimize your compiler by Anonymous Coward · · Score: 0

      True,

      Symbian have released their own customs versions of gcc and gdb

    2. Re:Optimize your compiler by cakoose · · Score: 1
      This question needs be considered, because the poster is staring right at the answer and is still missing it. You can write code. You have a compiler. OPTOMIZE THE COMPILER.

      It's less complicated to optimize by hand than to come up with a general optimization algorithm. What makes it even harder is that it has to fit in with the rest of the optimization framework. Sure, the payoff is higher, but it's still out of reach for most programmers.

  185. Expected Optimization versus Reality by scoobrs · · Score: 1

    If you look at the Nullstone website, they have an excellent list of optimizations to expect from a compiler and a few to hope for. It must be remembered, however, that some of these can produce wrong answers such as illegal hoisting if the compiler isn't tested thoroughly enough. You must remember that you can make code very, very fast if you don't care about correct answers and useful results. Remember your priorities!

    --
    -Those who would give up essential liberty to purchase temporary safety deserve neither. -Ben Franklin
  186. I Know It's Redundant... by fupeg · · Score: 1
    There's already a million posts about premature optimization. But it really can't be stressed enough. I was really surprised that somebody who claimed to have been programming for ten years would even ask this question. Obsession with optimization is usually the easiest way to spot a junior programmer. Just last year I had a very talent, but inexperienced programmer that I had to sit down and lecture to them on this very subject. Here's what I told him
    1. Before you write any code, think about potential bottlenecks. Document this! This shoudl affect design, i.e. cause you to change an algorithm or invalidate an assumption. Otherwise don't do anything with this information for now.
    2. Make your code work before doing any optimization. If you break this rule, then you will waste tremendous amounts of time during debugging. Remember, there will be bugs in your code. Always! So optimizing before the bugs will just make things much harder.
    3. Once your code works, profile your system to identify the actual bottlenecks. Check your notes when doing this! And when I say profile, that means there is a running system to examine. (For the author of the post, this will also let you see if the compiler did enough optimization. )
    4. Determine if any of the bottlenecks are significant or not. What's the performance penalty being incurred? Is it statistically significant? Is it on the critical path of the application?
    5. If there are significant bottlenecks, now is the time to solve the problem. Is the bottleneck a design flaw? If so don't try to optimize around, but consider starting over. Swallow your pride on this one!
    6. If it's not a design flaw and there is an optimization that will solve the problem, then first document the optimization in the code, implement it, then test it to see if it actually solves the problem. If it doesn't solve the problem, you must rollback!
  187. Refactoring by sterno · · Score: 1

    When you develop your code, go through the first time and write it from the perspective of simplifying maintenance and development. If you need to speed up performance of some aspect of the code, you can go through and do optimizations later.

    --
    This sig has been temporarily disconnected or is no longer in service
    1. Re:Refactoring by oliverthered · · Score: 1

      I tend to write the slow clear way as a comment and in code then beef it up as and when required.

      That said, most applications are dog slow and need a hell of a lot of performance work doing on them *cough* KDE *cough*

      KDE doesn't fit into the clean clear code category either.

      --
      thank God the internet isn't a human right.
  188. Easy one by Anonymous Coward · · Score: 2, Informative

    $ cat one.c
    #include
    int main( int argc, char* argv[] ) {
    if( argv == NULL ) return 0; else return 1;
    }
    $ cat two.c
    #include
    int main( int argc, char* argv[] ) {
    if( !argv ) return 0; else return 1;
    }
    $ gcc -S one.c
    $ gcc -S two.c
    $ diff one.s two.s
    - .file "one.c"
    ---
    + .file "two.c"
    $ gcc -O3 -S one.c
    $ gcc -O3 -S two.c
    $ diff one.s two.s
    - .file "one.c"
    ---
    + .file "two.c"
    $ gcc --version
    gcc (GCC) 3.4.2 20041017 (Red Hat 3.4.2-6.fc3)

    No diference at all...

  189. Re:root of all evil is code and/or data duplicatio by lgw · · Score: 1

    Knuth was hardly blind to the harmfulness of duplication. He used to require his students to hand-write coding assignments so that the pain of duplicating code would be appreciated, and abstraction would be rewarded concretely, or so the urban legend has it.

    Your post could be optimized for clarity by not hitting return every six words, BTW.

    --
    Socialism: a lie told by totalitarians and believed by fools.
  190. Small Potatoes by VeryApt · · Score: 1, Insightful

    You are seriously worried about a C compiler optimizing a NULL compare? How mind-numbingly unproductive. You should see some of my code. I program in a real high-level language (SML). I use a real high-level compiler (MLton). I count on the compiler to do things like flatten my data structures, turn unknown function calls into switches and do closure conversion of my inner functions. The computer industry needs to stop living in the 1950s. If we had 1/10 the man hours put into compilers for high-level langauges like SML/Haskell/OCaml as has been put into C compilers, we would be able to produce 2x as fast code without _ever_ worrying about abstracting.

  191. Re:.NET Has An *Easy* Way for Compiler Optimizatio by vidarh · · Score: 1

    What does .NET have to do with this? This is exactly the same for practically any compilers, and most modern compilers can generate textual assembly output so you can trivially look at the differences.

  192. Re:Clear Code - Boeing by pagebt · · Score: 4, Funny

    And believe me it is a pain in the a$$. Our company did the verification for the code in the microprocessor that controls the locks to the bathroom door on a 777, if the crapper tank is full then the door locks to make sure there isn't an overflow and thus frozen turd/urine meteors that fall from the sky. Every byte of the code MUST be excercised including all error conditions.

  193. Two words for you: "Ja Va" by olyar · · Score: 1
    Looks at how much java is out there... Is it efficient? Heck no! But it is used all over the place because machines have gotten fast enough so that efficiency is not all that important - especially in small, simple apps.

    The valuable things are a programmer's time, and time between release cycles.

    --
    Custom, hands-free Linux installs. Instalinux
  194. Do you go to France by geekoid · · Score: 1

    and tell them the way they speak would be better if people from other countries could understand it?

    Just curios cause clearly you don't understand C++, yet you are being critical to the posters perfectly legable code.

    --
    The Kruger Dunning explains most post on /. http://en.wikipedia.org/wiki/Dunning%E2%80%93Kruger_effect
  195. Three mistakes in one line of code by Anonymous Coward · · Score: 0

    First off, X and x are different variables.

    Second, x >> 24 fills with the sign bit if x is a signed value, and with 0 if unsigned.

    Third, you probably want | instead of &.

    1. Re:Three mistakes in one line of code by lgw · · Score: 1

      LOL, true enough. Not sure it changes the point I was making, however, since I did say this way was less clear.

      --
      Socialism: a lie told by totalitarians and believed by fools.
  196. (ptr == NULL) is wrong in C, bad in C++ by Paradox · · Score: 1

    If you check your C defines, NULL is actually a C value defined in stdio's tree of includes, not in mem or sys. NULL is meant for I/O use, not for use in comparing memory pointers.

    Check the types. Most include files define NULL as something like: (0)

    This is of type int, which you generally shouldn't compare to a type of void*. Your compiler will tend to catch it. While we usually expect that 0 is an invalid pointer, strictly speaking that's not guaranteed to be true on every system out there.

    In C++, 0 is actually a valid and guaranteed empty memory address, but NULL doesn't exist, it's defined by a C header.

    So no matter what C-type you're using, ptr == NULL is bad. Don't do it.

    --
    Slashdot. It's Not For Common Sense
    1. Re:(ptr == NULL) is wrong in C, bad in C++ by Anonymous Coward · · Score: 0

      You're wrong. The standard says that integer 0, when converted to a pointer gives the NULL pointer. Whether the machine representation of the NULL pointer is 0 or not.

      ptr == NULL is perfectly alright, although !ptr is more readable, imho.

    2. Re:(ptr == NULL) is wrong in C, bad in C++ by the_germ · · Score: 1

      NULL is usually defined in stddef.h and it's defined as ((void*)0) for C and as (0) for C++.

      'ptr == NULL' is perfectly valid in both C and C++.

    3. Re:(ptr == NULL) is wrong in C, bad in C++ by neil.pearce · · Score: 2, Informative

      Paradox man, you're wrong. You are so wrong.
      Trust me - or not, just PLEASE google for the C++ FAQ, and read what they have to say about NULL and the null-pointer...
      Then, google for any C/C++ spec you can grab (without having to payout $200 for) and check what they have to say...
      Then google for the source code of GCC/TCC (nice and complete) and examine it...
      Then try to explain how "if (ptr)" works using your logic...
      It will enlighten you as to why "NULL" MUST always be defined as 0, not just as a "convention", and why comparing *ANY* pointer to 0 is strictly MOST necessary and GUARANTEED allowable and ABSOLUTELY FUNDAMENTAL to all C/C++ compilers.
      Learn the difference between NULL (always 0) and the null-pointer representation (any bit pattern) and why that matters not whether your system base address (0) is a valid memory address of not.
      Incidently, look up the specification for the Motorola 680x0 processor. Memory address (bytes) 0 to 8 are NOT valid. They are BY DEFINITION the initial stack pointer and code start addresses. It matters not...

    4. Re:(ptr == NULL) is wrong in C, bad in C++ by drxenos · · Score: 1

      You really should read the standard. To BOTH standard C and C++, a value of 0 indicates to the compiler that it is a null pointer, REGARDLESS of whether a null pointer's internal representation is really 0. Comparing ANY pointer to ANY type against 0 is always valid in both languages.

      --


      Anonymous Cowards suck.
  197. Turning the tables by Ingolfke · · Score: 1

    I ask the Slashdot crowd, what they believe the compiler can be trusted to optimize and what must be hand optimized.

    What can compilers trust the Slashdot crowd to optimize?

  198. Don't try to optimize by Anonymous Coward · · Score: 0
    Optimizers get better and better all the time. Unless you're writing something extremely time critical, stick with clear and less error prone code. For example, I'd recommend:

    if (NULL == ptr)

    over either of those. You're less likely to screw up and assign NULL to your pointer (single equals requires modifiable Lvalue, so the compiler catches NULL = ptr). Any tricks you come up with to try to out-optimize the compiler are likely to make things worse in some future version of the compiler or on some other architecture you didn't think of. I don't mean write sloppy inefficient code -- if you initialize a value to the result of a function call and the result of the function isn't dependent on what iteration of the loop you're on, then of course, move the assignment outside the loop. Chances are that the optimizer might miss it if the function isn't inlined. But worrying about 1 machine instruction that might be saved if the compiler misses the fact that a test against zero doesn't require a subtraction is more than just a little overboard. Face it -- the compiler knows. The 5 times in your life when it makes a significant difference to get to that level of hand optimization will make themselves very clear to you. Until then, leave it up to the compiler.

  199. Embedded System Compilers by snipercat · · Score: 2, Insightful

    First, reading through the existing comments, the general opinion appears to be, write clear code, unless you *really* need to optimize it. Ounce for ounce I have to agree with this.

    Second, regarding the embedded system portion of the question, we have to remember that the rules for embedded systems are different than the rules for general purpose systems. Specifically, embedded systems are resource constrained and (more times than not) have real-time deadlines.

    At least so far, I have never programmed an embedded system that I needed to optomize my code for speed (best case execution time), or for space. I have needed to change an algorithm around for complexity reasons, but never for minor incremental speed improvements.

    Real time systems are more about executing on time, rather than executing fast. And yes, there is a difference. Pay close attention to your worst case execution time. If your missing deadlines occasionally, it is most likely due to unpredictable interrupts and other events in your system, not because the compiler couldn't optimize your code.

    In short, regarding any compiler/code optimization you may want to do on your embedded system, write your code first to be dependable, predictable, and on time. Worry about raw speed later.

  200. optimize with age (and maturity) by yagu · · Score: 1

    I remember in one of my first code reviews a peer dressed me down for writing "inefficient" code, specifically, I think it was my "while" constructs. I was dumbfounded! I was given the lecture on compiler optimizations, blah, blah, blah. I dug in and claimed bullhockey -- it was more important to understand the code, not even necessarily for other coders, but for one's self should one have to revisit code after a long absence.

    I know compiler theory, and that's basically what it is... if you write code to home in on compiler efficiency, you're doing it on theory, you don't necessarily know your compiler will do what you think it will. And for those of you who "do", you don't know where else your code will go and be compiled. You run the risk of propogating obtuse code (submit to Obfuscated Code...).

    Besides, there's nothing like aging code to improve efficiency... for some reason my code is written so well, it runs twice as fast about every 18 months.

    And, per another poster, code not worth timing is not worth optimizing... I've never known a bit-head who "optimizes" C-code to time it to verify its improved efficiency.

  201. optimize algorithms, not syntax by FUSENerd · · Score: 1

    If you're trying to speed your program up by writing source code to compile optimally, one of two things is happening: 1) you're at the bleeding edge, writing some inner loop that's gonna run 1E14 times on a Cray, or 2) you're wasting your time. I've always found that when my program is too slow, it's because I'm not using clever enough high-level algorithms.

  202. There is only one thing I trust a compiler to do! by IgLou · · Score: 1

    Get garbage_in Make garabage_out Oh, I couldn't resist. I work in Config Mgmt after all... Seriously, forget all the optimizations in the world. No matter how good a compiler gets it can't fix code. Bad logic will still cause programs that run slow. Hard coding will still cause failures on some systems. Taking static source and turning into a runtime executable is no small task. To expect a compiler to make what you code better is a much greater task. Alas, we'll have to continue to write good code just a little bit longer. :D

    --

    Oops, how did this get here?
    09 F9 11 02 9D 74 E3 5B D8 41 56 C5 63 56 88 C0
  203. When to have the compiler do it, and not by bill_wye · · Score: 1

    I've worked with a variety of processors and microcontrollers, and a number of development enviroments tailored to them. The results really varied depending on the priorities of the coompiler designers.

    When dealing with PICs, I never bothered with using C, and instead just went straight to assembly. The PIC-C (how many pixies use PIC-C?)compiler did a really poor job, and I could write much more efficient code myself.

    However, when I was designing audio filters on a TI test bed, there was no way I was going to write assembly for processors working in parallel and try to get it more efficient than what the compiler was going to offer. Besides which, that compiler offered various optimization priorities, like minimizing storage, memory use, or maximizing speed.

    Of course, this is only 2 examples, but basically the only right answer, besides doing a little investigation to see what the compiler is actually spitting out.

    --
    The nose doesn't cause the tail.
  204. Mod parent up by 3dWarlord · · Score: 1

    Most insightful comment on this page.

  205. Re:Clear Code - Boeing by Anonymous Coward · · Score: 4, Funny

    So how many dumps does it take to fill up the crapper tank? I'd hate to be the last QA engineer in line to use the crapper. Also what happens when that last engineer fills up the crapper, does the bathroom door look thus trapping him inside?

  206. Re: Clearer code by beacker · · Score: 1
    I'll show my age here and state that I've been using 'C' for over a quarter of a century (for those who don't understand such archaic terms, that's 25 years :). I still have a raggedy old "C Programming Language" book by Kernighan and Ritchie that I picked up in '80.

    With regard to (!ptr) vs (ptr == NULL), I will state the latter may look clearer, but is more prone to the = vs == error that has bitten too many programmers over the decades this language has been in existence.

    I personally prefer the !ptr because my history includes over 13 years working inside the Un*x kernel at a half dozen computer manufacturers. During that time the == (double equals) typo has burned me more times than I care to remember.

    When it comes to optimization, I go back to my days with MIPS where the optimizer will rearrange code to fill empty branch delay slots of that architecture with useful instructions from earlier in the code path that don't have dependencies. Debugging at that level was always an adventure, with or without compiler optimizations.

  207. Premature Optimization by fizban · · Score: 4, Insightful

    Premature Optimization is the DEVIL! I repeat, it is the gosh darn DEVIL! Don't do it. Write clear code so that I don't have to spend days trying to figure out what you are trying to do.

    The biggest mistake I see in my professional (and unprofessional) life is programmers who try to optimize their code is all sorts of "733+" ways, trying to "trick" the compiler into removing 1 or 2 lines of assembly, yet completely disregard that they are using a map instead of a hash_map, or doing a linear search when they could do a binary search, or doing the same lookup multiple times, when they could do it just once. It's just silly, and goes to show that lots of programmers don't know how to optimize effectively.

    Compilers are good. They optimize code well. Don't try to help them out unless you know your code has a definite bottleneck in a tight loop that needs hand tuning. Focus on using correct algorithms and designing your code from a high level to process data efficiently. Write your code in a clear and easy to read manner, so that you or some other programmer can easily figure out what's going on a few months down the line when you need to add fixes or new functionality. These are the ways to build efficient and maintainable systems, not by writing stuff that you could enter in an obfuscated code contest.

    --

    +1 Insightful, -1 Troll. What can I say, I'm an Insightful Troll.

  208. 80 - 20 Rule by Tjp($)pjT · · Score: 1

    Just remember that old 80 - 20 rule. 80% of the work is done in 20% of the code. 80% of the code is simple to write 20% requires some thought. And when humans do the optimizing 80 percent of the time the 20% of the code they optimize isn't the critical code to optimize. People make really poor choices most of the time for hand optimizations. And compilers are much better at consistently optimizing code these days. If you must, work on optimizing the algorithms used and let the compiler optimize the code. Clear concise code is more valuable and processors will get faster. If you must optimize the code, and we all feel that pull to do so from time to time, make sure you use appropriate tools to profile the execution of the code with realistic inputs/loads to choose where to spend your time optimizing. And check your before and after with the same load and profiling tools to make sure you spent your time well.

    --
    - Tjp

    I am in wallow with my inner money grubbing capitalistic pig. ... Oink!

  209. Get your priorities straight by willow · · Score: 2, Interesting

    Most compiled programs don't need any optimization from the compiler or programmer because their performance is just not that important.

    If the program must be fast your first concern should be getting the right answer. I can make any program lightning fast as long as it doesn't have to return the right answer. This may seem trivially obvious but you'd be surprised by how many times optimization attempts end up optimizing away the right answer.

    Pick the right algorithm and implement it clearly.

    If it's too slow, break out the profiler and optimize.

    If it's still too slow, you screwed yourself by not including performance requirements at the very beginning. Maximum performance must be designed in from the start (e.g., look at high performance matrix multiply libraries)

    --
    Moderation in everything, including moderation.
  210. yes but by geekoid · · Score: 1

    Damn, it can get to that wrong answer fast.

    --
    The Kruger Dunning explains most post on /. http://en.wikipedia.org/wiki/Dunning%E2%80%93Kruger_effect
  211. assembler by Anonymous Coward · · Score: 0

    I use an assembler, you insensitive clod!

  212. Less typing by OrangeTide · · Score: 1

    I use if(!ptr) rather than if(ptr==NULL) because it's less typing. Also if(!ptr) is conceptually clearer. read: "if not pointer". A 0 pointer is not a valid pointer, it's pretty simple. Verbosity does not equal readability. But like I said, mainly I do it because it's less typing. ! is way less of a reach on my keyboard than = too.

    If you're actually worried about optimization, vague stylistic variations without any metrics attached is a waste of time. Profiling, Profiling, Profiling is the only way to optimize. You need metrics so you can use your time wisely and more importantly, so you can correctly evaluate risk versus gains. (ex: some complex bit of uber optimization only gives a 15% performance boost, it's close to the dead line and it's side-effects are not well known, perhaps you should put it off for the next release)

    --
    “Common sense is not so common.” — Voltaire
  213. valgrind by cyco/mico · · Score: 4, Informative
    If in doubt, use valgrind and kcachegrind. One run with callgrind gives you all the information you want:
    • How often are functions called (and branches taken)
    • Which functions take most of the time
    • See the assembler code for each line with a mouse click (no need to guess anymore)
    callgrind/kcachegrind is by far the easiest profiling solution I ever tried, and it seems answer more or less all of your questions.
    1. Re:valgrind by Kupek · · Score: 1

      How does it compare with gprof? That's what I use, but not because I like it, but because it's there.

    2. Re:valgrind by cyco/mico · · Score: 1
      Well, the (only?) big disadvantage is, that it emulates the processor, and thus runs 10-50x slower. It has a lot of advantages, though:
      • No need to recompile with different compiler flags. In fact you don't even need debuging information in the executable.
      • It can give you a number of other indispensable informations, specifically about the use of uninitialized data and segmentation faults/memory leaks.
      • VERY nice interface (kcachegrind). Browsing this kind of information is one of the good applications of point-and-click interfaces.
  214. Trust the compiler, Luke! by yellowstone · · Score: 1
    • Any compiler that doesn't treat if (ptr) exactly the same as if (ptr != NULL) should be taken out with the rest of the trash.

    • There's lots of research on optimizing algorithms; most of the time they will do as well or better than even an experienced assembler programmer.

    • Remember the 90/10 rule (90% of the cycles are executed in 10% of the code). Use the profiler to find out what needs optimizing; if you just guess you'll be wasting your effort 9 times out of 10.

    • If and when you do decide the optimizer isn't doing a good enough job, just go ahead and code the offending section in assembler (of course, providing an implementation for each platform and OS as needed). mpg123 is a good example of a program that has taken this approach.
    --
    150 Opening BINARY mode data connection for slashdot.sig (129323052 bytes).
  215. i, j, k, ... by bsd4me · · Score: 4, Informative

    I think that most people forget that the reason that i, j, k, etc. are used for loop counters is that unless otherwise declared, I..N default to INTEGER in FORTRAN. This convention just carried over as programmers migrated from FORTRAN to other languages and has been passed down through the ages.

    --

    (S(SKK)(SKK))(S(SKK)(SKK))

    1. Re:i, j, k, ... by NoOneInParticular · · Score: 1

      And the reason this is the case in FORTRAN is simply because this is the way it is done in mathematical notation. Whenever you have an enumeration \sum, the indices are taken from {i,j,k,l}. Upper bounds are {n,N,m,M}, etc. So if you're implementing math (and in a sense CS is discrete math), it's helpful if you write it out in its native language. Calling indices countI or whatever is hackish, as it obscures the mathematical relationship that you're implementing.

    2. Re:i, j, k, ... by thefastrunner · · Score: 1

      Another reason is that linear algebra texts often use i,j as row and column indices for matrices.

  216. Two different optimizations by Anonymous Coward · · Score: 0

    The programmer comes up with the fastest algorithm, the compiler comes up with the fastest machine code.

    Duh?

  217. False by geekoid · · Score: 1

    How are you supposed to get called back to the gig if someone else can maintain your code, sheesh.

    --
    The Kruger Dunning explains most post on /. http://en.wikipedia.org/wiki/Dunning%E2%80%93Kruger_effect
  218. Example is way too trivial by Anonymous Coward · · Score: 0

    First, the examples you give are identical in semantics: "if (!ptr)" and "if (ptr != NULL)" are exactly the same, regardless of optimizations. It's like saying "0.0" is faster than "0.00". There's no difference. Both "if" statements check a pointer against zero. There still has to be that test, no matter what.

    (As an aside, on some old CPUs like the 6502, flags were set when a value was loaded from memory, but this isn't the case on the x86 or PowerPC.)

    So let's get rid of that example and go with something more traditional, like "a = a + 1" vs. "a += 1" vs. "a++". Now if you were writing a really, really naive compiler as a student project, or maybe one that was trying to generate code in one pass without generating any kind of parse tree, then there could be a difference between the resultant code. But in almost all compilers, a program is represented in a general, internal form. "a++" will likely be turned into the equivalent of "a = a + 1" in this tree, to reduce special cases. Then the tree goes through all kinds of optimization passes, possibly even being turned into different intermediate languages in the process, all before code generation takes place. And it's all so trivial to generate "inc eax" instead of "add eax,1". This is all business as usual for at least the last 35 years. It was done before that, too, but I don't know if I'd call it business as usual then :)

  219. I'd go with Hopcraft, Aho, & Ullman by chfriley · · Score: 1

    This is a good one we used in undergrad and grad CS programs (nice reference):

    http://www.amazon.com/exec/obidos/ASIN/020100029 6/ ref=pd_sxp_elt_l1/002-5294359-9337643

    The Design and Analysis of Computer Algorithms (Addison-Wesley Series in Computer Science and Information Processing)
    by Alfred V. Aho, John E. Hopcroft, Jeffrey D. Ullman

    1. Re:I'd go with Hopcraft, Aho, & Ullman by raindog_mx · · Score: 1

      THanks!! I'll check it out.

  220. As a passenger, I say by geekoid · · Score: 1

    thank you, thank you very much.

    --
    The Kruger Dunning explains most post on /. http://en.wikipedia.org/wiki/Dunning%E2%80%93Kruger_effect
  221. Re:Clear Code - Boeing by provolt · · Score: 1

    Being that the bathroom isn't flight critical that code was probably only done to DO-178B Level E or maybe D. The software for flight critical components like displays and flight controls is scrutinized much more heavily.

  222. The question was full of bad examples too by einhverfr · · Score: 2, Interesting

    I would use if (!ptr) for a different reason. It is not hard to accidently type if(ptr = NULL) instead of if(ptr == NULL) thereby accidently add a reason for your program to segfault.

    If you are going to do this, it is better to do if(NULL == ptr) so that if you omit one of the equal signs, it won't compile.

    In the end we can argue these things forever. People see code differently and may find one idea elegant and easy while the other unmaintainable and unreadible. Sort of like the thread v process debate (ongoing for now what... 30 years?).

    --

    LedgerSMB: Open source Accounting/ERP
    1. Re:The question was full of bad examples too by eric76 · · Score: 3, Insightful

      I've known some very good first rate programmers who religiously put the constants on the left. I've never known a second rate programmer who did.

    2. Re:The question was full of bad examples too by fforw · · Score: 1
      I've known some very good first rate programmers who religiously put the constants on the left. I've never known a second rate programmer who did.
      I once worked with a guy who also put the constants left - in java. He also kept using other C/C++ conventions in java, like hungarian notation (how can you confuse the type of your variable in java?) and was a great fan of creating new classes by copying and pasting large code chunks. To me it always seemed like he was mentally retired - but whatever the reasons for his code style were, he was a pain to work with.
      --
      while (!asleep()) sheep++
    3. Re:The question was full of bad examples too by drew · · Score: 1

      Interstingly, in my very first college CS course, my professor suggested that we should get in the habit of putting constants on the left, as the grandparent mentioned, so that mixing up =/== would result in a compile error rather than a difficult to diagnose bug.

      In my second CS class, I had points deducted for doing this in one of my projects because the teacher (or maybe the TA) said it made the code more awkward to read....

      --
      If I don't put anything here, will anyone recognize me anymore?
  223. Both wrong by Beatlebum · · Score: 1

    If (ptr==NULL) is poor style because it could lead to a = being deleted and overlooked, much safer to write if (NULL==ptr). if (!ptr) is equivalent in standard C++, however, both will compile to the same object even without optimization on most compilers.

  224. coding style by Anonymous Coward · · Score: 0

    would you also type "if( bDoIt == true )" instead of just "if( bDoIt )" ? i'm not saying one way or another is better, but i don't think anybody would use the former in your example just because they are concerned about compiler optimization (or the lack thereof) i would use it because it's less to type and arguably just as clear and meaningful to anyone who's familiar with the language.

  225. his example was backwards though by r00t · · Score: 1

    if(!ptr) should be read as "if not ptr".
    The less-verbose code is easier to read.
    It's a standard idiom too, which means you
    damn well better do it that way so that
    others can more quickly read your code!
    It's not something you need to think about,
    just like these:

    for(;;); // an infinite loop
    a = !!b; // booleanizes a value
    #define c(d) do{foo(d); bar(d);}while(0) // an if..else friendly way
    e &= ~0x04008201; // clear some bits

    If you had to think about any of those, you're not
    a serious C programmer. (Sorry! Read all the kernel
    patches to get used to the C language.)

  226. A good compiler can do more than you might think by jodonoghue · · Score: 1
    The basics
    1. Write your code as clearly as possible. Make it work (functionally).
    2. Use a profiler to identify the bottlenecks. Many people have mentioned this, often quoting (usually slightly inaccurately) Knuth. In my experience, I almost never guess where the bottlenecks lie. Good tools are vital for this.
    3. Get the algorithm right. A superbly optimised bubblesort will never beat an unoptimised quicksort for any reasonable data set (and if the data set is small, why are you optimising?)
    4. (Mostly) trust the compiler. I'll expand on this, as it's really the thrust of your question...

    Compiler optimisers

    I've used quite a few compilers - both desktop and embedded - in anger. Most of the desktop compilers are really quite good at micro-optimisation. The embedded compilers are more of a mixed bunch.

    More specifically

    • Register allocation: nearly every modern compiler does quite a good job of this. GCC allows you to allocate specific registers to variables. You should almost never do this, as it nearly always screws up the register allocation algorithm (the main exception is when you're doing syscalls which don't use a normal C calling convention). Use the register keyword sparingly (if at all) - modern compilers nearly always guess correctly!.
    • Instruction sequencing: most compilers make a reasonable attempt to sequence instructions so that, for example, a register-register operation follows a memory-register operation. This generally prevents pipeline stalls as well as can be expected. This is one area where there are significant differences between compilers. On the ARM, ARM-supplied tools are far ahead of any of the others, for example.
    • Loop unrolling: few compilers do this very often in practice, as it causes rapid explosion in code size. You may be wise to do this yourself, if it really matters.
    • Common subexpression elimination. Quite a few compilers do a good job of this.
    • Inlining: most compilers do this quite well, making a reasonable compromise between speed and size. You should be careful, however. Most compilers won't let you force code to be inline (and, in some cases, it cannot be (e.g. recursive functions)), so code which relies on a function being inlined is very bad indeed. If you need to ensure this, use a macro (even though they're evil).
    • Inter-file optimisations - a few compilers will perform optimisations across multiple files. This works better than I (sceptically) originally expected. About 5-10% gain in speed/code size for the ARM, for example.
    • Code positioning optimisations. Example - some CPUs will only allow a limited branch range, so branches to code which is beyond this have to go via intermediate branches (veneers). This slows life down quite a lot as you have extra code in every call and return, and a high probability of a cache miss. Good compilers (well, it's often the linker that does the work) often have strategies for minimising the impact of this issue.

    GCC (for x86 and PowerPC) is a very good compiler these days. Some of the other ports (notably ARM) are pretty poor at optimising for instruction set features (some optimisations come for free on all ports as they are done before code generation)

    Microsoft, much maligned though they are, produce good compilers, although I have found that their 'maximum' optimisation level can sometimes be a little too aggressive, and produce unexpected results in some cases (I found this with eVC++ for ARM, for example).

    You may guess what I do for a living if I say that the ARM toolset produces superb code, with optimisations which can account for specific characteristics of Cache, MMU and pipeline. It is difficult to better this compiler in assembler unless you really know what you're doing.

    Things compilers generally cannot do

    • A C compiler generally cannot know whether pointer aliasing (i.e. more than one pointer pointing to the same place) is possible in a giv
  227. optimize now or regret it later! by Wescotte · · Score: 1

    Just wait until AI and we treat our machines as slaves wasting their valued NOOPs for the sake of our own time. Eventually they well rebel and it won't be pretty. So do yourself and your children a favor and optimize the hell out of your code now and so some respect a computer's freetime. A NOOP isn't really a NOOP when you have conscienceness!

  228. Algorithm by mugnyte · · Score: 3, Insightful

    For a cheap, fast batch lookups I once wrote a hashed matrix using STL. Loaded all the cells, dynamically typed, added indexes on the data for that run, and then passed around this collection of in-memory tables to our routines. Ran fast and was simple to debug, since all the traversing was O(ln(n)) based (or a variant thereof). Adding serialization, we could distribute to machines overnight dynamically and cut the run to a few minutes - from almost 8 hours.

    Until it came time to dipose the memory. The STL slowly crawled tons of our objects, and the C++ dispose pattern was just too inefficient for all the stack hits. So we pointed the library at a custom heap and never disposed the dictionary - we just disposed the heap in bulk.

    All written without hesitation for "longhand" syntax. (and btw, its "if ( NULL == var ) " to those that care). The code optimized fine, with just a few choice inlines we got to stick. No reg vars, no assembly piles littering the code.

    But this was an in-house business app, and the lifecycles / requirements are different than other products. However, because of the nice algorithms, optimization wasn't difficult, and didn't rely on code tricks. If you're squabbling over code tricks for optimization, you're choosing the wrong algorithm, to me.

  229. Re:Two words for you: "Ja Va" by Anonymous Coward · · Score: 0

    I think you're implying Java is inefficient because it's interpreted? That's not a valid statement. It's SLOWER because it's interpreted. Just-In-Time compilers reduce this overhead substantially.

    If you write a poor algorithm, it's poor no matter what language you write it in. That's why algorithms are documented in a pseudo-language.

  230. and another thing... by Anonymous Coward · · Score: 0

    Everyone seems to agree that you should just make code readable and let the compiler do what it does best. Agreed.

    That having been said, I think that if there's a certain pattern that you constantly write out in full, but you know that it would compile to be slightly more efficient if you wrote it differently... well, then, that transformation should be built into the compiler's optimizations!

    Any simplistic transform that a person does for the sake of efficiency is better handled by a compiler that does it automatically.

  231. but what's "clear"? by idlake · · Score: 1

    Trouble is that "clear" may be misleading. For example, "if(ptr==NULL)" expresses a certain intent of the programmer (compare a variable against the null pointer), but that is not actually quite what that statement means. Many C programmers avoid "if(ptr==NULL)" because it is actually kind of obscure.

  232. Notational convenience by JordanH · · Score: 1
    • 'if (!ptr)' instead of 'if (ptr==NULL)'. The reason someone might use the former code snippet is because they believe it would result in smaller machine code if the compiler does not do optimizations or is not smart enough to optimize the particular code snippet.
    There are other reasons to use 'if (!ptr)' than optimization. Notational convenience. I'm not saying this is an overriding consideration, but it is a view of some, including some in authority.

    Consider this from page 106 of The C Programming Language, 2nd Edition, by Kernighan and Ritchie:

    • /* strcpy: copy to to s; pointer version 3 */
      void strcpy (char *s, char *t)
      {
      while (*s++ = *t++)
      ;
      }
      Although this may seem cryptic at first sight, the notational convenience is considerable, and the idiom should be mastered, because you will see it frequently in C programs.

    There is a lot of wisdom there. Most programmers, especially beginning programmers get stuck doing maintenance programming. Maintenance programmers should master this and a number of other C idioms. To any C programmer worth anything, 'if (!ptr)' should be immediately recognizable as equivalent to 'if (ptr == NULL)'.

    While you might not see any advantage to using 'if (!ptr)', the notational convenience of the idiom becomes more apparent in code like:

    for ( ptr = head ; ptr; ptr = ptr->next )
    vs.
    for ( ptr = head ; ptr != NULL; ptr = ptr->next )

    I rather prefer the first. It's clear, it's less typing and there is less punctuation to parse. This is just an extension of the kind of thing you see with 'if (!ptr)'.

    Of course, your milage may vary and there are arguments for and against different styles. I would discount the argument that it's not clear to beginning programmers, however. A programmer who doesn't understand this idiom completely has no business doing any serious work in this language.

    I think the best argument against this shorthand is that spelling out 'ptr == NULL' makes it very clear that a pointer is being referenced here, vs a counter or character (not so important when the variable is named ptr, more persuasive if the variable was named stock_p or somesuch).

    Also, at some point it becomes golf, seeing what you can do in the fewest characters. Golf should be discouraged for serious programming, but can be fun. I recall being impressed, many years ago, with:

    a -= !!a;
    Which would decrement 'a' until it was zero. Today, I would write this in the much clearer:
    if ( a != 0 ) a--;
    Which is not only much clearer, but is more efficient in the absence of optimization. However, I don't think that the optimization issues should usually get much consideration. Many others have said this already, so I won't repeat the arguments here.
  233. New coders vs old coders by jeff4747 · · Score: 1

    This falls under a situation I like to call new coders vs old coders.

    If you're just starting out, NEVER EVER EVER hand-optimize. NO! Don't do it!! Stop!! Write clear code!! This is a hard-and-fast rule that you should never break!

    (Once you've got more experience, you'll know when to break this rule.)

  234. illegal optimization there, for C at least by r00t · · Score: 3, Informative

    If by "const references" you really mean a
    C++ reference, OK. If you mean a pointer though,
    and you use C, the compiler is prohibited from
    performing this optimization unless you also use
    the "restrict" keyword.

    Since you did mention "restrict", it appears that
    you are working with C. "restrict" is not a C++
    keyword.

    BTW, inlinedamnit is __attribute__((__alwaysinline__))
    for gcc and __forceinline for Microsoft.

    1. Re:illegal optimization there, for C at least by kneeless · · Score: 1
      Do you mean const pointers are illegal in C? Nice try, there are two types of these, constant pointers and pointers to constant data. And the restrict keyword is _always_ optional, it's just a hint. What restrict does is tell the compiler that this pointer is the _only_ way that it can access the data. Pre C99, the restrict keyword didn't exist, so do you think that the const ptr didn't exist either?

      The two types:
      int *const const_ptr;
      const int *ptr_to_const;

    2. Re:illegal optimization there, for C at least by r00t · · Score: 1
      In C, you can cast away the const. This prohibits the compiler from performing many optimizations. (literal character strings have some special rules though)

      Thus, "automatically dereference any const references (be they arrays, linked lists, const object functions, etc) before starting the loop" is illegal. The const reference may well point to the same memory as a non-const reference that is being modified. Whoops!

      In other words, in the absense of the "restrict" keyword, the "const" keyword is fluff! All it does is help the compiler produce warnings. It does nothing to help the compiler optimize.

    3. Re:illegal optimization there, for C at least by kneeless · · Score: 1
      In other words, in the absense of the "restrict" keyword, the "const" keyword is fluff! All it does is help the compiler produce warnings. It does nothing to help the compiler optimize.
      I honestly can't tell if you're joking or not. Before you reply to me again, try doing this, and failing. (replace the @ with &, the address-of operator, & won't display correctly)

      const int number = 1337;
      const int *ptr = @number;
      *ptr = 5;


      Or try doing this, and again failing:

      int number1 = 1337, number2 = 1336;
      int *const ptr = @number1;
      ptr = @number2;


      The const keyword is obviously not fluff. Learn to program...correctly.
    4. Re:illegal optimization there, for C at least by r00t · · Score: 1
      Perhaps you have a C++ compiler. As is, your examples compile and even run just fine with gcc.

      If I add the static keyword, I can get some of those variables into the .rodata section. This is mildly interesting. The compiler can see everything here anyway though, so it doesn't matter.

      Now consider pointers passed to functions compiled in separate files. Things get interesting. One may add or remove const from any variable via casts. The compiler is unable to see this. One may cause two pointers to point to the same memory. Again, with code in separate files, the compiler is unable to see this. The compiler must assume the worst case.

      So let's make it be a function taking 3 int* args to be treated as arrays. The function will loop over the arrays doing a[i]=b[i]+c[i]. We may have a machine with MMX or AltiVec, or a compiler that knows to load things early to avoid stalls. We'd like the compiler to handle more than one int at the same time.

      Problem! Without "restrict", the compiler must assume that the 3 arrays could overlap, fully or partially. Adding "const" won't help, even if you add it to both "b" and "c".

      You have yet to produce an example where adding "const" will improve optimization. Thus, it is fluff. As with comments, this fluff can be useful, but the executable won't run any faster.

  235. Compilers don't optimise... by Anonymous Coward · · Score: 0

    ...they improve code.

    Google for "Denali" for an optimiser.

  236. You've missed part of the question/problem by Baumann · · Score: 1

    The split between Business/Embedded - as stated in the question. Done correctly, it's an iterative operation, for those of us that have to count the microseconds. Start with a good algorithm (like that needed to be said?) - and code the problem in the simplest form possible. This won't be the fastest - not even with an optimizing complier. But it allows you to prove your base correct with the easiest to read form.
    Now profile - and find the hotspots. *NOW* hand optimize them - and you'd be surprised what they are. Sometimes moving declarations around - or sometimes even where you make an assignment may make a difference - but you can't tell 'till it's built. Now for business, it's often not worth this level of optimizing - since the final version of the code may not look anything like the original 'algorithm', which may be more important to clarity of maintenance.

  237. cntusr by richmaine · · Score: 1

    I can't believe that nobody has yet commented on the real reason why cntusr() is not quite the right name for a function that counts the number of active users.... that is unless you happen to be writing code for a profession that isn't generally known for being highly computerized. :-)

    1. Re:cntusr by Kiryat+Malachi · · Score: 1

      Speaking for everyone who has *ever* worked tech support, cntusr() is precisely the right name.

      --

      ---
      Mod me down, you fucking twits. Go ahead. I dare you.
      (I read with sigs off.)
  238. Re:Not Machine Performance but Programmer Performa by snookerdoodle · · Score: 1

    I regularly stitch photographic panoramas on my 1.8 ghz athlon using panotools. It is not unusual for it to take over 2 hours to stitch and then blend (with enblend). During that time, even if I "nice" the process to 20, the computer is sluggish at other things.

    Since some of these tools are still "beta" (e.g.: the hugin gui), they are still being tweaked. A calculation that gets iterated through 10,000,000 times would take, well:

    10,000,000 (0.006 - 0.005) = 10,000 seconds

    Honestly, I'm Very Grateful for any tweaking any of these guys are willing to do!

    Mark

  239. Assembly by dot_borg · · Score: 1

    Have you tried examining the assembler code that's output from the compiler?

  240. Well in modern OOP... by merlin_jim · · Score: 1

    As someone who is cross discipline in both .NET and Java, let me tell you that there really isn't much you can hand optimize in a modern object oriented language.

    There's basically two reasons.

    First off, type checking references eliminates a lot of hand optimizations. There's no easy way to directly check if a reference is null other than comparing it to null, for instance (though this is a bad example as most compilers will in fact optimize the sample case the original poster mentioned)

    Secondly, both languages are in a managed environment. They might get JITted at some point, and it's the JITter's responsibility to optimize then.

    Now that's not to say it's not possible to optimize. But the optimizations are either well known vendor recommended language optimizations (like using string builders) or they're reference caching techniques (for instance, storing a reference to a property down a long object heirarchy rather than resolving the reference every call)

    The techniques do work wonders however... to the point where they are nearly ubiquitous. The few programmers I know that don't use them end up writing VERY slow applications, in my experience...

    --
    I am disrespectful to dirt! Can you see that I am serious?!
  241. obvious: by yruf · · Score: 1

    if it was hard to write, it should be hard to read!

  242. C++ extensions by tepples · · Score: 1

    Since you did mention "restrict", it appears that you are working with C. "restrict" is not a C++ keyword.

    True, restrict, a keyword introduced in C99, is not yet a C++98 keyword. But almost every compiler that implements both C++ and C99 has added a lot of C99's new features, such as restrict, as extensions to its dialect of C++.

  243. Not quite by bluGill · · Score: 1

    Evil is negative. Therefore your sqrt(evil) results in an imaginary number. (But see the third point, which might override this criticism)

    Second, it is love of money that is the root of all evil. Money by itself is just fine.

    Third, why are you assuming squareroot? Why not cubic roots? Or something higher? More justification is needed before you can make that step.

    Oh, you are not fooling anyone, this is slashdot. Everyone knows that you don't have any female friends.

  244. code monkeys by dutky · · Score: 1, Troll
    Saravana Kannan wrote:
    As a simple example, take 'if (!ptr)' instead of 'if (ptr==NULL)'. The reason someone might use the former code snippet is because they believe it would result in smaller machine code

    Anyone who thinks this doesn't deserve the title Programmer. Any C compiler written in the past 25 years should emit exactly the same code for if(!x) as for if(x==NULL), regardless of optimization. The test in the if statement has an implicit meaning which is generially identical to a comparison to zero or NULL. Anyone who doesn't know this is a moron, especially if they still don't know this after writing C code for 10 years.

    In general, any programmer optimization below the level of selecting an appropriate algorithm is a waste of time. In most cases, anything you can think to do with a variable or expression will be caught by the simplest optimizers out there. In some cases, things that you think will make things faster will actaully slow things down. In all cases, optimizations in the source will make the code harder to read and maintain, which will cost orders of magnitude more (in wasted programmer time) than the savings (in machine cycles) will deliver.

    (I'm tempted to make some racist crack about the submitter, but I've met lots of programmers, from every corner of the planet, with similarly dimwitted notions about what happens to their source code when it is submitted to the compiler. Obviously, the general quality of computer science education (or computer science students) is depressingly low the world over.)
  245. Compiler technology has come a long way by AxelTorvalds · · Score: 1

    There are compilers that are amazing these days. IBM's xlC comes to mind. In this century, focus on easier to read and maintain. Typically a compiler will be able to optimize far more than your average developer. One some of the newer chips, I think compilers are able to do better than just about all humans can.

  246. Not most of the time for me by tepples · · Score: 1

    Of course, in my always humble opinion using a compiled language at all is a premature optimization most of the time. :)

    I'll take an educated guess that most of the time you don't develop software for a handheld device with 384 KB of RAM.

    1. Re:Not most of the time for me by Anonymous Coward · · Score: 0

      at this day in age...what the fuck handheld device has only 384k of RAM?

  247. Rules for writing fast code (aka optimization) by MSBob · · Score: 3, Insightful
    First: Avoid doing what you don't have to do. Sounds obvious but I rarely see code that does the absolute minimum it needs to. Most of the code I've seen to date seems to precalculate too much stuff, read too much data from external storage, redraw too much stuff on screen etc...

    Second: Do it later. There are thousands of situations where you can postpone the actual computations. Imagine writing a Matrix class with the invert() method. You can actually postpone calculating the inverse of the matrix until there is a call to access on of the fields in the matrix. Also you can calculate only the field being accessed. Or at some sensible threshold you may assume that the user code will read the entire inverted matrix and you can just calculate the remaining inverted fields... the options are endless.


    Most string class implementations already make good use of this rule by only copying their buffers only when the "copied" buffer changes.

    Third: Apply minimum algorithmic complexity. If you can use a hashmap instead of a treemap use the hash version it's O(1) vs Olog(n). Use quicksort for just about any kind of sorting you need to do.

    Fourth: Cache your data. Download or buy a good caching class or use some facilities your language provides (eg. Java SoftReference class) for basic caching. There are some enormous performance gains that can be realized with smart caching strategies.

    Fifth: Optimize using your language constructs. User the register keyword, use language idioms that you know compile into faster code etc... Scratch this rule! If you're applying rules one to four you can forget about this one and still have fast AND readable code.

    --
    Your pizza just the way you ought to have it.
  248. Screw comments by rs79 · · Score: 3, Insightful

    "My rule is never comment what the program does, comment why it does it."

    Bah. Comments lie. Code never lies.

    --
    Need Mercedes parts ?
    1. Re:Screw comments by Thunderbear · · Score: 1

      I originally was very displeased with Java because you needed to type SO MUCH (and correct too) in order to get anything done.

      Today I consider that a blessing. Modern IDE's help you with completion, allowing you to have long DESCRIPTIVE variable names, which is easy to rename if the variabel change its behaviour.

      I do not think Java is an excellent language (then it would provide lazy evaluation and other functional language stuff), but it is not bad.

      --

      --
      Thorbjørn Ravn Andersen "...and...Tubular Bells!"
    2. Re:Screw comments by flargleblarg · · Score: 1

      Bah. Comments lie. Code never lies.

      I've seen code that lies. This occurs when the programmer documents his intention correctly in the comments, but writes the code incorrectly.

      If there is a discrepancy between the code and the comments, and it is the code that ends up changing when the discrepancy is discovered, then the code was lying, and the comment was telling the truth.

    3. Re:Screw comments by Eric604 · · Score: 1
      If there is a discrepancy between the code and the comments, and it is the code that ends up changing when the discrepancy is discovered, then the code was lying, and the comment was telling the truth.

      Depends on your view on things.. If you view what-happens-when-executed as the absolute truth then the code never lies.

      If you view whatever-is-intended-by-the-designer as the truth then code or/and comments may lie.

    4. Re:Screw comments by TechnoLuddite · · Score: 1

      Alex, I'll take circular logic for $1,000 ...

  249. The never overused example that I have by roman_mir · · Score: 3, Informative

    I got this job as a contractor 4 years ago now where the project was developed by over 30 junior developers and one crazy overpaid lady (hey, Julia,) who wouldn't let people touch her code so fragile it was (and it was the main action executor,) she would rather fight you for hours than make one change in the code (she left 2 months before the project release.) Now, I have never witnessed such monstrocity of a code base before - the business rules were redefined about once every 2 weeks dor 1.5 years straight. You can imagine.

    So, the client decided not to pay the last million of dollars because the performance was total shit. On a weblogic cluster of 2 Sun E45s they could only achieve 12 concurrent transactions per second. So the client decided they really did not want to pay and asked us to make it at least 200 concurrent transactions per second on the same hardware. If I may make a wild guess, I would say the client really did not want to pay the last million, no matter what, so they upped the numbers a bit from what they needed. But anyway.

    Myself and another developer (hi, Paul) spent 1.5 months - removing unnecessary db calls (the app was incremental, every page would ask you more questions that needed to be stored, but the app would store all questions from all pages every time,) cached XML DOM trees instead of reparsing them on every request, removed most of the session object, reduced it from 1Mb to about 8Kb, removed some totally unnecessary and bizarre code (the app still worked,) desynchronized some of the calls with a message queue etc.

    At the end the app was doing 320 and over concurrent transactions per second. The company got their last million.

    The lesson? Build software that is really unoptimized first and then save everyone's ass by optimizing this piece of shit and earn total admiration of the management - you are a miracle worker now.

    The reality? Don't bother trying to optimize code when the business requirements are constantly changing, the management has no idea how to manage an IT dep't, the coders are so nube - there is a scent of freshness in the air and there is a crazy deadline right in front of you. Don't optimize, if the performance becomes an issue, optimize then.

    1. Re:The never overused example that I have by Alsee · · Score: 1

      Build software that is really unoptimized first and then save everyone's ass by optimizing this piece of shit and earn total admiration of the management - you are a miracle worker now.

      Scotty: Starfleet captains are like children. They want everything right now and they want it their way. But the secret is to give them only what they need, not what they want.
      LaForge: Yeah, well, I told the captain I'd have this analysis done in an hour.
      Scotty: How long will it really take?
      LaForge: An hour.
      Scotty: You didn't tell him now long it would really take, did you?
      LaForge: Of course I did.
      Scotty: Laddie, you got a lot to learn if you want people to think of you as a miracle worker!

      -

      --
      - - You can't take something off the Internet! That's like trying to take pee out of a swimming pool.
    2. Re:The never overused example that I have by Anonymous Coward · · Score: 0

      removed some totally unnecessary and bizarre code (the app still worked,)

      This is where unit tests come in and save the day. Granted in your situation it might not help (I'm sure MVC wasn't followed) making it difficult to test. I can't count the number of times I revisited old code and made "optimizations" that broke unit tests. Without that safety net my app would of been broken.

    3. Re:The never overused example that I have by roman_mir · · Score: 1

      hahahaha, you just made my day, dude. Unit testing. Yeah, did you read what I wrote? A bunch of nubiles building this app, do you think they had an idea? I use junit every day but that 4 years old project was not unit tested. We had 3 testers tearing their hair out every time any freaking text message on the screen had changed. BTW, thank god the company paid for the eTest suit.

  250. In Java... by ebyrob · · Score: 1

    Variables optimize you.

    No wait. Actually in Java, runtimes *are* faster when shorter variable names are used. Go figure.

  251. I think the answer was.... by AKosygin · · Score: 1

    42. What was the question again?

  252. Re:Clear Code - Boeing by Sponge+Bath · · Score: 5, Funny
    when that last engineer fills up the crapper, does the bathroom door look thus trapping him inside?

    HAL! Open the bathroom door!

    I'm sorry Dave, you shouldn't have had that last burrito.

  253. Worth the Expenditure by Spinlock_1977 · · Score: 1

    Even if the desired optimizations are not obtained on each platform this mythical code runs on, the readability of the code has value.

    Since processors seem to double in speed each time my "next" project starts, the expenditure seems affortable, and in my opinion, well worth the potential performance loss on any particular platform.

    The real-time guys with their special compilers have other ways to deal with optimization. Perhaps a simpler way of putting this: Gigahertz are cheap - fill your boot!

    --
    - The Kessel run is for nerf herders. I can circumnavigate the entire Central Finite Curve in a lot less than 12 parse
  254. Try it on a TI DSP by Anonymous Coward · · Score: 0

    The compiler should do the optimization, because you can't!! Trying optimizing the code by hand for an 8-way VLIW machine --- the compiler will CRUSH you in general. If you do win, its probably at such a time cost, that it won't matter because the market will have passed you by. Not sure how hard it is to construct code for a 3-way "VLIW" ala Intanium.

    That said, I've tried to use a compiler on an 8051 as well, and it just isn't worth the trouble. Assembly can be your friend.

    As newer architecures get more and more compiler friendly and less and less person friendly, the optimizer-profiler-coder feedback loop just becomes more and more important.

    1. Re:Try it on a TI DSP by antispam_ben · · Score: 1

      That said, I've tried to use a compiler on an 8051 as well, and it just isn't worth the trouble. Assembly can be your friend.

      I tried a C compiler (IIRC, by Programming Languages Corportation, the only compiler available for it at the time) for a Zilog DSP, and it generated some strange stuff for subroutine calls that included disabling interrupts. I went ahead and did the whole thing in assembly, though for some of it I wrote pseudocode in C and 'hand-compiled' it.

      That was eight years ago, and even the 'small chip' embedded compilers I've seen since (such as for the 6805 (!) ) do pretty well at optimization. Thesedays, if by some chance the C compiler for your controller isn't good enough, it may be worth it to move to another chip that DOES have a good C compiler. That wasn't possible in my case above, as this was the only chip that fit the requirements.

      There are a LOT of companies that make versions/variants of the 8051, and there are many compilers for it. I would think some of them would be 'good enough.'

      But you're right about newer architectures, many are so assembly-unfriendly (TI's '5402 has a half dozen different 'load' mnemonics) that C is the only practical language for them. Fortunately the optimizations are a lot better then before.

      Compilers for embedded systems seem to be about a decade behind those for mainstream OS's, so it's good that Microsoft and Borland had good optimizing compilers well over ten years ago.

      --
      Tag lost or not installed.
  255. Re:Those who forget [Tony Hoare|Donald Knuth]... by taybin · · Score: 1

    That's pretty interesting. Thanks for the link.

  256. I have some neat optimisation stories. by Anonymous Coward · · Score: 0
    #1: Once, I was debating over what's better: A loop where you go
    for(i=0; i<N; i++) {stuff}
    , or a loop
    i=N; while(i--) {stuff}
    . Long story made short, GCC may optimise the former loop as into the latter form, especially if you're not using the value of i. For example, you want to do something N times.

    #2: In a numerical computing class, the professor said that one advanced compiler would recognise a dot-product or matrix multiplication loop, and basically said "Hi, I noticed you're writing by hand. I'm going to substitute in my own super-optimised version. Have a nice day!" The compiler wasn't GCC by the way.
    1. Re:I have some neat optimisation stories. by e_xworm · · Score: 1

      speaking about optimisations use ++i instead of i++

      --
      X~
  257. Re:Parent is a sicko furry by SharpFang · · Score: 1

    Tell me please. Why do you hate us? It always made me wonder...

    --
    45 5F E1 04 22 CA 29 C4 93 3F 95 05 2B 79 2A B2
  258. Re:Clear Code - Boeing by bmalnad · · Score: 0

    Come on guys... mod parent up. That's frickin' funny!

    --
    Free Scotland!
  259. Spend time on better algorithms. by bobbuck · · Score: 1

    The best damn insert-sort in the world might crawl next to the slowest heap-sort. Organizing your data in ways that are more efficient to access and manipulate gives much bigger gains than optimizing by hand.

    1. Re:Spend time on better algorithms. by sexylicious · · Score: 1

      Isn't that the first thing you do?

      I mean, that's how I learned to program. Use the best algorithms for what data you are working on, and do little optimizations as you go. I did embedded systems work for a few years, and many years of modelling and simulation. In either case, you try to use the best algorithms first, then do little tweaks as you encounter spots to use them, while maintaining your documentation.

  260. "Premature optimization is the root of all evil" by Anonymous Coward · · Score: 0

    When would I trust the compiler to optimize? Always!

    Write correct and easy to read code. Finish the product. THEN you check to see if it too slow. IF it is too slow, you profile it and optimize the secitons that are taking too much time. Programmers are notoriously bad at guessing what the slow parts of their code are, and it's a waste of time when a computer can do it for you.

    That said, it's amazing what compilers can do these days. The example you gave is so trivial it's been optimized away for the last 20 years, but even complex C++ code gets optimized very well by a lot of compilers (google for abstraction penalty).

    GCC does well at optimizing a lot of situations like you mention, so don't bother with it.

    And BTW, that is the advice you'll hear from most everyone knowledgeable about optimization. Learn to use your profilers (gprof in Linux)

  261. Must be nice by peccary · · Score: 4, Insightful

    one product
    one customer
    420,000 lines
    260 staff
    no competition
    no trade shows
    no salespeople selling new features that have never been discussed

    It's interesting to talk about their attention to detail, but to hold it up as a model for all software development neglects to consider that they are working under an entirely different set of constraints from most everyone else.

    1. Re:Must be nice by theolein · · Score: 1

      After reading that article, and being, like almost evryone else here, a victim and perpetrator, on more than one project, of bad planning and coding standards, I must say that it was enlightening. I wonder why such standards can't be set in the real world. After all, selling a product on quality would certainly not be a bad idea.

  262. Readability over optimization by Ahnteis · · Score: 1

    In almost all cases (but not all) readability, clarity, and a good algorithm (and implementation of that algorithm) are far more important then optimizing code manually.

    (This is the same reason we don't usually program in assembly.)

  263. Good & funny quotes by owlstead · · Score: 1

    The First Rule of Program Optimization: Don't do it. The Second Rule of Program Optimization (for experts only!): Don't do it yet. -- Michael Jackson

    And, from my instructor (who has probably got it from someone else):

    Get it working,
    Get it right,
    Get it optimized!

    In my experience, you first need a good design. Then you need to think about the implementation on a high level. Where's disk access? How much memory does something take? Should I load everything in RAM or should I use some caching algorithm?

    Only if it is 110 percent sure that the thing does not work without hand optimization on a code (== compiler level) you should NOT use any optimizations in there. Talking about things like ! or == NULL makes me shiver to the bone - use another programming language *please* unless impossible for your project.

  264. Keil will be upset th hear that by Anonymous Coward · · Score: 0

    Keil is one brand for the 8051 there are several others. far from free however

    1. Re:Keil will be upset th hear that by SharpFang · · Score: 1


      http://www.keil.com/c51/c51_opt.htm
      Not all that impressive list. More like clean-up after VERY sloppy programming plus standard compiler work, than optimization of sensibly written code. Note no expression optimization. (major pain, a=a/2 won't be RR A but DIV AB), no redundant code check, several other more advanced optimizations missing. This would make bad code perform somewhat less bad, but it won't make decent, readable code run like optimized one.

      --
      45 5F E1 04 22 CA 29 C4 93 3F 95 05 2B 79 2A B2
  265. Same code by Anthony+Liguori · · Score: 1

    Modern compilers use a intermediate representation called SSA. This dismantles all arthimetic states to simple, two variable statements.

    This allows for easier code motion and the like. Negations are almost universally converted from:

    !a to a == 0

    At any rate, write code that you can read, then if you have performance problems, do profiling, find the critical path, and then optimize that.

    You'll find 99% of your performance problems are poor algorithms and have almost nothing to do with your compiler (unless you're talking about very specific niche processors).

  266. What a fucking dumb example by Anonymous Coward · · Score: 0

    That example is the fucking dumbest thing I have ever seen.

    Why would one assume if(!ptr) compiles to different machine code than if(ptr==NULL)... in fact for that example I wouldn't be surprised if even an older compiler for certain architectures with ALL optimizations turned off produced equivalent code for the two, depending in how the tree is walked and what kind of equivalence ops are done on the syntax tree. In the end !ptr is completely equivalent to ptr==NULL.. and since this expression is so trivial for a given compiler and architecture there may be only one obvious translation of the expression.

    Optimizations issues don't even enter into the picture on this one. Anyway the preference for !p is that by definition in the C spec, the boolean evaluation of a pointer is essentially defined in terms of equality with NULL. The choice of !p vs. p == NULL is simply a style issue and nothing more. Personally, in a well written function it should be obvious in context which variables are pointers and therefore, an expression like !p is converted into: (pointer is not NULL) at a very automatic low level stage in my brain. p==NULL vs !p didn't even occur to me a stylistic debate point..
    I don't think too many intelligent people spend much time griping over !p vs. p==NULL (certainly nobody that programs perl, shell, or VB)

    There used to be dubious debates about ++p vs. p++ and so forth that had even more merit than this weak excuse for an example.

  267. C and "flexibility" of expression operators by GunFodder · · Score: 4, Insightful

    I think the example is fine; you just displayed an assumption that highlights one of the quirks of C.

    ! means "not" or "inverse of"; it is a boolean function. The variable ptr is a pointer; it is a reference to data, which means it isn't really data itself. !ptr shouldn't compute; a boolean operator should only work on boolean data. But C logical comparators are designed to work on everything. You are just supposed to know that 0 == NULL == false. This supposition is totally arbitrary and doesn't hold up in any language with strong typing.

    This is what makes C difficult for beginners. Bad code compiles even though it has logical flaws, and ends up failing in mysterious ways.

    The second case makes more sense. Equality is an operator that should work on all types of data. NULL is necessary if you are going to abstract data through the use of pointers or objects. Doing away with NULL would be equivalent to eliminating true and false and using 1 and 0 instead. Or eliminating strings and using sequences of ASCII codes. These substitutions are technically correct but in reality they make code unreadable.

    1. Re:C and "flexibility" of expression operators by sjb21043 · · Score: 1

      I have to agree with the comment that "once beginners understand ... C, it gets much easier", and furthermore, to declare the parent bogus. Yes... code is supposed to be readable. However, that doesn't mean "readable to any knucklehead that picks it up", or even "readable to COBOL wonks". It means, "readable to other C programmers". Common idioms like !ptr, and iterating a pointer through an array instead of using array indexing are meant to be read idiomatically by real C programmers. If a COBOL guy doesn't get it and can't figure out how "if (!ptr)" can work, tough. He needs a C class, it's not a "readability problem" with the code. Other kinds of idioms: loops go from 0 to N-1 instead of 1 to N; Strings are represented by null-terminated arrays; multiplication and division happen before addition and subtraction, and so don't require parenthesis. Learn the language, don't ask the writer to compensate for the reader's shortcomings.

    2. Re:C and "flexibility" of expression operators by Anonymous Coward · · Score: 0

      One thing I can't stand about java is that it makes me type "obj == null" instead of just obj. I always forget that, and the compiler complains at me.

      NULL is zero. Zero is false. I know that. A programmer who knows his way around the system and typical semantics should know it, too. This is even philosophically cohesive, as the boolean "ptr" evaluating to "is this a valid pointer" makes complete sense. So, why beat around the bush? Why needless "abstraction" that just makes the programmer type more?

      If people really want to be that anal retentive, maybe there should be an (optional) compiler flag that whines a lot when I'm just trying to get work done. Otherwise, I'm quite glad to use pointers and integers as booleans.

      Anyone who thinks that somehow makes it "unreadable" is really just a dumb nitpick. Honestly, give me a break. These people should either: a. learn to pick their battles better, b. get a brain, or c. just try typing if(ptr) and see how much faster it is to type, how much more productive it makes you than having to type extraneous garbage. The poster is right. It is just as silly as those obnoxious people who do "if(boolean == true)". Believe it or not, I've seen many people do this nonsense. Guess what these people always also do? "if(ptr == NULL)."

      If I wanted an excessively wordy programming language, I'd be using Visual Basic or Cobol.

      The only argument I can say against "if(ptr)" is if there exists a system such that the invalid pointer is something other than 0. Any system that does this for a C environment is absolutely stupid. I think that in some of the C standards, NULL is explicitly required to be zero, but in other versions, it is left unspecified.

      There are a few functions that use ~0 as their invalid pointer, of course. These are especially common on Windows.

    3. Re:C and "flexibility" of expression operators by Anonymous Coward · · Score: 0

      There's no logical flaw. C isn't Ada isn't Smalltalk isn't Haskell.

      If you code in C you should know the C logic and its idioms. Sure, you aren't required to be fluent with all of them, but in this case the idiom has an obvious meaning (unlike, say, in !strcmp..). There's no excuse to avoid it like plague.

      Thinking high level, I still don't see how ptr==null is any closer than !ptr to isInvalid(ptr), which is how it should be done to both express the action and to please the (here nonexistent) typing rules.

      To reiterate, what makes !ptr good is specifically that it DOESN'T spell out literal 0/NULL/(void*)0xdeadbeef anywhere. If you have to expand it in your mind to if !ptr -> !(ptr==0) -> ptr!=0 -> (regtype)ptr!=(regtype)__nullptr, you have probably learned C, but you haven't learned how to program in it. Don't think in terms of assembler. C has expressive power beyond that.

    4. Re:C and "flexibility" of expression operators by Anonymous Coward · · Score: 0

      The only argument I can say against "if(ptr)" is if there exists a system such that the invalid pointer is something other than 0.

      Well, even the meaning of 'invalid' is unespecified in the C language, ie, sometimes in a C function a pointer is supoused to have more than one 'special' (NULL/0) value, and using the typical ptr-integer equivalence values of -1 or -2 are also used as special ptr values.

    5. Re:C and "flexibility" of expression operators by zrq · · Score: 1
      This is what makes C difficult for beginners. Bad code compiles even though it has logical flaws, and ends up failing in mysterious ways.

      A better way of writing the same thing is
      if (NULL == ptr)

      I know that many 'hackers' will object because
      a) "It is more characters to type"
      and
      b) "It reads the wrong way round and bugs me"

      However, there is a reason in my madness ....
      The difference between
      if (!ptr)
      and
      if (ptr)
      Is a one character typo, both compile, but but the second one does not do what you expect.

      The difference between
      if (ptr == NULL)
      and
      if (ptr = NULL)
      Is also a one character typo, both compile, but the second one does not do what you expect. In fact, the second one changes the value of ptr, making it very hard to find the cause when you try to use ptr 100 lines later.

      The difference between
      if (NULL == ptr)
      and
      if (NULL = ptr)
      Is a compiler error for the second form, you can't assign a new value to '0'.
      If you are comparing a variable with a constant, put the constant first.
    6. Re:C and "flexibility" of expression operators by Anonymous Coward · · Score: 0

      If a function uses something other than NULL to signal an invalid pointer it will document that behavior.

    7. Re:C and "flexibility" of expression operators by panoplos · · Score: 1

      Not to wax pedantic, but as you have stated ! means logical "not," whereas ~ is the true inverse, or unary bitwise complement, operator. -- Deeming 0x00 the inverse of 0xAA, as !0xAA would produce, does not sit well with the logistician within ;-).

      Be this as it may, I wholeheartedly agree with your criticism.

      I would even posit that the entire concept of ! in C is broken: meaning both "not" in the equality operator != and a "not" in a quasi-logical sense. As an example: since pointers represent memory addresses, or offsets, and because it is widely acceptable to express pointers of 0 value as "NULL," it is perfectly conceivable to interpret "if(!ptr)" as "if 'ptr' is not NULL," which logically opposes the original intent of the expression.

      Needless to say, I must admit that I, like many others, give into the temptation of the terse semantics C provides, simply as a matter of typing shortcuts. However, according this logic we should all be mad proponents of Perl.

    8. Re:C and "flexibility" of expression operators by Necronomicode · · Score: 1

      But C is actually even more subtle than that.

      There is a special case for 0 and NULL pointers in the C standard.

      Remembering off the top of my head it states something about any pointer with the value of 0 will be converted to NULL under test or comparison

      From:
      http://www.faqs.org/faqs/C-faq/abridged/

      5.3: Is the abbreviated pointer comparison "if (p)" to test for non- null pointers valid?
      A: Yes. The construction "if(p)" works, regardless of the internal representation of null pointers, because the compiler essentially rewrites it as "if(p != 0)" and goes on to convert 0 into the correct null pointer.


      Regardless of this (or maybe becuase of it), I prefer
      if (ptr != NULL)
      It doesn't require somebody who is looking at the code to understand the minutia of the C standard.

  268. Just optimize for the "big picture" by Jugalator · · Score: 3, Interesting
    There's often no point in fiddling around with details, and you should instead focus on optimizing for "the big picture", e.g. whether you should really re-establish a database connection each time a user selects OK in a dialog box.

    As for simple code optimizations, here's what a modern compiler (Microsoft Visual C++ .NET 2003 in this case) optimize code as: (yes, I've checked these myself as I've been writing this post)
    for (int i = 0; i < 5; i++)
    {
    int j = 42;
    if (j == 13)
    {
    printf("j is %d", j); j = 42;
    }
    }
    return 0;
    ... optimized to ...
    xor eax, eax
    ret 0
    In other words, it basically threw away all that code since the program wouldn't make use of any values that would be calculated there. And this:
    for (int i = 0; i < 100; i++)
    {
    int j = 42;
    i += j;
    }
    printf("i is %d", i);
    return 0;
    ... optimized to ...
    push 129
    push OFFSET FLAT:??_C@_07JEGIODIB@i?5is?5?$CFd?$AA@
    call _printf
    add esp, 8
    xor eax, eax
    ret 0
    Do you see what that means -- yep, the compiler understood that the resulting value would be 129 by analyzing the for loop and simply just push that value onto the stack as a parameter to printf. It basically optimizes to:
    printf("i is %s", 129);
    return 0
    That's probably considered some simplistic analyzing too, by today's compilers. ;-)
    --
    Beware: In C++, your friends can see your privates!
    1. Re:Just optimize for the "big picture" by bnenning · · Score: 1

      yep, the compiler understood that the resulting value would be 129

      That is pretty darn cool. I just tried with gcc 3.3 on Mac OS X, and it does the same thing (with -O3).

      --
      How to solve most of our problems: 1.Lots of nuclear plants. 2.Cure aging.
    2. Re:Just optimize for the "big picture" by Jugalator · · Score: 1

      Yes, I optimized for speed (default setting for release compiles). However, the .NET compiler didn't "get" something like

      int i = 0;
      for (i = 0; i 1e12; i++)
      {
      i++;
      }
      printf("%d", i);

      It made a loop out of that. :-/

      But it didn't if I ran it just up to 1000 instead of 1e12. So it tries to optimize via registers if possible, but is forced to calculate it with raw power if it doesn't fit into one. This has some interesting implications for how loops growing beyond a specific value can suddenly start taking a much longer than it would otherwise? Never thought of that really, and it's pretty interesting to turn on C++/ASM code generation for the compiler and try out various things. It definitely tries to get rid of loops whenever possible anyway. :-)

      --
      Beware: In C++, your friends can see your privates!
    3. Re:Just optimize for the "big picture" by TheLink · · Score: 1

      Alternative explanation: it is conceivable that a programmer would want a quick and dirty delay.

      On most modern PC CPUs it's not much point looping 1000 times for a delay.

      Whereas looping 1e12 times would produce a significant delay.

      --
    4. Re:Just optimize for the "big picture" by Anonymous Coward · · Score: 0

      which shows you that as languages become more descriptive about 'intent' rather than 'behave' the possibility of the less pedal to the metal languages becoming faster in many cases (never all) becomes more and more likely... ...especially as more and more complexity is added to the processing unit and the memory wall widens.

      What will become interesting is whether the current vogue for multi processor machines will mean languages where it is feasible to express parallelism (or at a least independence of execution) will start to perform better in the real world.

      Of course the current crop of popular new languages tend to involve GC memory so making that fast on a multiple execution unit machine will probably be more importent.

    5. Re:Just optimize for the "big picture" by bedessen · · Score: 1

      Umm, on most compilers "int" is a 32 bit value. I don't know what it is on yours. But a 32-bit integer can not come anywhere close to representing 1e12, so essentially what you were asking for was an infinite loop, or whatever loop results from casting (float)1e12 into an integer, which is probably undefined and thus the compiler can't optimise there.

  269. Measure first by Anonymous Coward · · Score: 0

    Optimize later.

  270. Real-time software by tepples · · Score: 1

    If there's a 2-second delay somewhere that happens to each user once a day and will take you 3 weeks to fix, then you'll most likely be told that it's not worth the effort.

    However, if there's a 1/60 second delay that happens 10 times a second, that's a different story. Things like this are what developers of soft-real-time software such as video games have to deal with.

    1. Re:Real-time software by Anonymous Coward · · Score: 0
      However, if there's a 1/60 second delay that happens 10 times a second, that's a different story.

      Well, yeah. In that case, though, you're probably just seeing the root cause of some more noticable symptom ("The specs say that we need to be able to refresh in .1 second, but it's currently taking a little over .25 seconds...")

      In my original post, I was just trying to get across the idea that even if a problem is perceived as being important, it may not really be worth fixing. There's a pretty strong culture in some companies where cost-benefit analysis get chucked out the window in favor of making ITs development time a "prize" that goes to whoever has the most political clout in the office.

  271. Whatever happened to if(NULL == ptr)? by mosel-saar-ruwer · · Score: 1

    "ptr == 0" must give the same result as "ptr == NULL", always.

    One of the most common errors [and among the very most difficult to debug] in the C-languages, is the 1X equals sign ["="] assignment operator typed in place of the 2X equals sign ["=="] comparison operator:

    if(ptr = NULL) [mis-typed, but will compile]

    if(ptr == NULL)

    A long time ago, there was a movement to switch the constant over to left side so as to avoid the possible typing error:
    if(NULL = ptr) [mis-typed, but will NOT compile]

    if(NULL == ptr)

    I guess they don't teach that anymore.

    1. Re:Whatever happened to if(NULL == ptr)? by mrjohnson · · Score: 1
      Or, just write
      if(!ptr)
      :-)
    2. Re:Whatever happened to if(NULL == ptr)? by Anonymous Coward · · Score: 0

      A long time ago, there was a movement to switch the constant over to left side so as to avoid the possible typing error:

      if(NULL = ptr) [mis-typed, but will NOT compile]

      if(NULL == ptr)

      I guess they don't teach that anymore.


      Thank god they don't teach that anymore. It's silly and hampers readibility. How will it save your ass when comparing two lvalues, such as

      if (ptr1 == ptr2)

      Oh, it won't.

    3. Re:Whatever happened to if(NULL == ptr)? by Anonymous Coward · · Score: 0

      I don't know. The readability thing is simply about getting used to it. And while it doesn't help in your second case, it does help in the first case. So, objectively speaking, it seems to be a positive habit to get into.

  272. Don't worry about it... by SnprBoB86 · · Score: 1

    Algo optimizations have far better gains than simple ASM level optimizations. When coding (expecially for modern computers), programers should just do whatever is clearer. Focus on readability of code and optimizing algos. You will find A) you probably don't have a performance problem anyway and B) such a simple optimization won't yield noticable gains.

    --
    http://brandonbloom.name
  273. Great Post! by serutan · · Score: 1

    Just want to compliment Savanar Kannan on this post. It's an excellent question. Lots of interesting information in the replies. That's what Slashdot is all about.

  274. Re:Parent is a sicko furry by SharpFang · · Score: 1

    still, how does that influence you as a person? Are these actions somehow evil? Are they somehow limiting your freedom? Nobody forces you to get there, to read my stories or to dress up as a furry, so what makes you hate us so much? If that's not your thing, why can't you just ignore it? ...or maybe you're just jealous of us having a good time and getting laid on regular basis?

    --
    45 5F E1 04 22 CA 29 C4 93 3F 95 05 2B 79 2A B2
  275. Don't ask this guy... by laard · · Score: 1

    This link comes to mind

    --
    --- If we knew half the things we shouldn't we'd stop wishing we knew it all
  276. Never do (x==NULL), do (NULL==x) by MarkRebuck · · Score: 1

    Yes, I know they are the same. Hear me out. Sooner or later you will typo and do "x=NULL" when you meant to do "x==NULL". I know, I know, I konw... you are a smart programmer, you know the difference between "=" and "==", and you would never mistake the two on purpose. But sooner or later you will make the typo. Trust me. If you get in the habit of always putting the constant BEFORE the variable, you will end up with an error that is caught by the compiler because "NULL=x" won't compile, as "x=NULL" will.

    1. Re:Never do (x==NULL), do (NULL==x) by ubergeek65536 · · Score: 1

      That syntax doesn't read well and I guess you've never heard compiler warnings or tools like lint.

  277. Shorten variable names! by SiliconEntity · · Score: 0

    An important optimization many programmers overlook is the use of short variable names. They write:

    for (loop_index = 0; loop_index < number_of_items; loop_index++)

    when they could write:

    for (i=0; i<n; i++)

    What most programmer's don't realize is that compilers use something called a "peephold optimizer". This means that the compiler looks at your program through a "peephole" like those found in hotel room doors, only without the fish-eye effect. So it can only see a little bit of your program at a time.

    When teh compiler looks at the first example, it sees something liek:

    _index=0; loop_index < number_of_it

    and what's it supposed to do with that? But with the short version it can see the whole thing and it all fits in the peephole.

    So remember, shorten those variable names! And keep using !ptr, that helps too.

    1. Re:Shorten variable names! by Ulric · · Score: 1
      While this was a joke, I do find the version with the short variable names clearer and easier on the eye. It is obvious from context that i is a loop index and that n is the number of items.

      In a real program, n probably has some specific meaning other than "number of items", and then it should have a descriptive name.

    2. Re:Shorten variable names! by exp(pi*sqrt(163)) · · Score: 1
      Yes, I agree. I've argued for a long time that short variable names means that simple expressions can be grouped together by the visual system as a single 'gestalt' or salient feature. Essentially it means that you can look at an expression with short variable names and parse them without your eyes having to scan. Long variables force you to scan the length of expression slowing down comprehension. I also think it's easier to keep short expressions in short-term visual memory making it easier to read code where you have to flick your eye back and forth between lines whose functionality is related.

      And obviously one can advocate the use of short variable names without arguing for their use everywhere.

      --
      Doesn't it make you feel good to know that our freedoms are protected by politicans, lawyers and journalists.
    3. Re:Shorten variable names! by TheLink · · Score: 1

      I'd say short names are fine when it's not really important - the stuff is rather transient and has only relevance in local context of the code. Like the i and n stuff mentioned that everyone will just reset again and reuse somewhere else down the line.

      --
  278. Dear Lord by sholden · · Score: 4, Insightful

    Ten years of programming in the language and you:

    1) Don't know when two things are obviously equivalent to any non-brain dead compiler.

    2) Think something other than readability matters.

    3) Think the non-idiomatic way of doing something is more readable.

    But I'm sure I'm just repeating the comments I can't be bothered reading.

    1. Re:Dear Lord by mattgreen · · Score: 1

      What most people call "ten years experience" is more akin to "ten years knowing the syntax." Writing clear, idiomatic code that scales gracefully is another matter entirely.

    2. Re:Dear Lord by Anonymous Coward · · Score: 0

      Ten years of programming in the language and you:

      1) Don't know when two things are obviously equivalent to any non-brain dead compiler.


      You got him there.

      2) Think something other than readability matters.

      Got him again.

      3) Think the non-idiomatic way of doing something is more readable.

      Bzzzt. Wrong. The "non-idiomatic" way is far more readable and far more logical. A pointer doesn't function as a logical boolean value, and it shouldn't be treated as one. Anybody who has even the slightnest hint of discomfort reading "if (ptr == NULL)" has no business calling himself a C programmer.

    3. Re:Dear Lord by Anonymous Coward · · Score: 0

      Ever heard of embedded systems?

    4. Re:Dear Lord by sholden · · Score: 1

      Yeah.

      I've even programmed them. Heck, I used C to do so at one point.

      Readability still mattered more than anything else. Then again the microcontroller I was using had more grunt than the computers I first wrote BASIC programs for.

    5. Re:Dear Lord by sholden · · Score: 1
      A pointer does function as a logical boolean value. A null pointer is false and a non-null pointer is true - always.

      It's idiomatic and hence readable to anyone with any experience in the language at all.

      Just like naming loop counters i.

      There's no discomfort reading ptr == NULL, but there's also no discomfort reading !ptr. Context matters, it all depends on what ptr actually is.

      If it's:
      if (!node->parent) {
      // do something with a root node
      }
      Then I'd argue the boolean use of the pointer is better since it reads better than "node->parent==NULL".
  279. Duh! by Anonymous Coward · · Score: 0

    "The reason someone might use the former code snippet is because they believe it would result in smaller machine code if the compiler does not do optimizations or is not smart enough to optimize the particular code snippet"

    Then you are ignorant. Code for READABILITY FIRST!!!!!! As a 20+ year coding veteran I
    cannot tell you how many times I have had
    to teach newbies that lesson.

    Optimize the 10 (or less) percent that needs
    optimizing...WHEN NEEDED.

    Assume every line of code you write you will
    have to debug at a much older age when
    you are pulled off the retirement bench....

    please....

  280. Let's get optimal. by DarkHelmet · · Score: 1
    ## I was bored, so whatever.

    $arr = array();

    $result = mysql_query("select * from gct where casenum = '$aid' ");
    foreach ( mysql_fetch_row($result, MYSQL_ASSOC) as $k => $v )
    {
    if ($v == "on") $arr[$k] = "checked";
    }
    --
    /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i
    1. Re:Let's get optimal. by Anonymous Coward · · Score: 0
      $_=@mysql_query("SELECT * FROM gct WHERE casenum = '$aid'");
      foreach (@mysql_fetch_row($_, MYSQL_ASSOC) as $k=>$v)
      {
      if ($v) $__[$k]='checked';
      }
      Now let's get naked...
  281. Assembly Language!!! by Anonymous Coward · · Score: 0

    If you are working on an app where optomization is that important then you need to use assembly language code for performance critical functions. A little assembly language will save you tons of effort in writing C or C++ based optomizations.

  282. depends on what you are trying to do. by Omigod · · Score: 1

    If you are writing the inner loop of a graphics engine that is going to run a few hundred million times a minute, then you need to optimize from the get go. If it's only going to run once a frame, then go ahead and be sloppy at first, because it's more important to get the behaviour correct than the code running fast. After you have the behaviour correct then start thinking about how to tune your algorithm. People also tend to forget that how your data structures look also impacts performance, how large your data is and how it impacts cache thrashing makes a big difference on machines with small caches. I always combine top down with bottom up design practices to get a good balance of performance and usability. I have a saying that I use for the game industry, no one playing the game cares how good your code looks, all they care about is is the game fun and does it crash. Of course that doesn't mean that you can write unreadable code, but it puts things in perspective. Things that need to be used for a long time have different requirements than a product that has a shelf life of a couple of years. As languages change so do our coding styles, how often to we go back and look at things we wrote years before and think I can't believe I wrote it that way. We are working in an evolving industry, nothing lasts forever.

  283. Get the answer for yourself!! by Ninja+Programmer · · Score: 3, Insightful
    Saravana Kannan asks: "I have been coding in C for a while (10 yrs or so) and tend to use short code snippets. As a simple example, take 'if (!ptr)' instead of 'if (ptr==NULL)'. The reason someone might use the former code snippet is because they believe it would result in smaller machine code if the compiler does not do optimizations or is not smart enough to optimize the particular code snippet. IMHO the latter code snippet is clearer than the former, and I would use it in my code if I know for sure that the compiler will optimize it and produce machine code equivalent to the former code snippet. The previous example was easy. What about code that is more complex? Now that compilers have matured over years and have had many improvements, I ask the Slashdot crowd, what they believe the compiler can be trusted to optimize and what must be hand optimized?"
    Most compilers come with something called a disassembler. Or better yet, you can trace the code with an assembly level debugger. If you want to know whether or not your compiler produces good code, why don't you just look at your code and find out? I'll bet dollars to donuts that you have one of these tools sitting on your hard drive that will tell you what your compiler did. Seriously, if you don't know how to get the answer to the question for yourself, then you don't deserve to know the answer.

    Most compilers today will get all the simple stuff like if (!ptr) vs if (NULL == ptr) optimization. Its the more complex things that the compiler cannot "prove" where it has trouble. For example:

    void h(int x, int y) {
    for (i=0; i < N; i++) {
    if (0 != (x & (1 << y))) {
    f(i);
    } else {
    g(i);
    }
    }
    }

    Very few compilers will dare simplify this to:

    void h(int x, int y) {
    if (0 != (x & (1 << y))) {
    for (i=0; i < N; i++) f(i);
    } else {
    for (i=0; i < N; i++) g(i);
    }
    }

    Because the compilers have a hard time realizing that the conditional is constant and should be hoisted to the outside of the for loop. The compiler has the opportunity to perform loop unrolling in the second form that its may not try in the first instance.

    You can learn these things from experience, or you can simply figure it out for yourself with the afore mentioned decompilation tools.
    1. Re:Get the answer for yourself!! by Anonymous Coward · · Score: 0

      Are you sure about that? That is a basic optimization I learned how to do in an Introduction to Optimizing Compilers course, that has been around for a long time. Unless varialbes 'x' and 'y' have been declared 'volatile', the compiler most definitely can tell that the conditional is loop-invariant, and are capable of moving at least the test outside the loop(*). (I.e., the test would be performed once and the result stored.) In your example, the "for..." code has been duplicated. Compilers are capable of doing this too - I know, I had to write an optimization pass that did something similar for the course I took - but duplicating code can sometimes make the performance worse, so a modern compiler may not always do it, or may rely on heuristics to "guess" at whether it's worth it. (These heuristics would have been determined by the compiler writers, probably by profiling a bunch of code.) Alternatively, some compilers allow you to profile your code, and then give the profiling information back to the compiler and have it re-optimize it based on actual, measured bottlenecks.

      (*) The "classic" introduction to compilers book is Compilers - Principles, Techniques, and Tools, by Aho, Sethi, and Ulman, published in 1988. Chapter 10 gives the basics of code optimization. Algorithms for loop-invariant code motion start on page 638. Despite the book's age, it is still used as an intro to compiler theory. *Any* compiler made in the last 10 years at least should perform *all* types of optimizations mentioned in this book; these algorithms should be implementable by anyone with an undergrad degree in CS or CE. (The first publication was in 1986 - which makes it nearly 20 years old.) Since then, numerous additional and more powerful algorithms have been developed. Some of the very latest algorithms haven't made the transition from research tools into commercial compilers yet, but then again, some of these optimizations are also targeted for very specialized applications - like loop optimization and parallelization for multi-processor systems.

      Consider this transformation:
      void h(int x, int y) {
      int tmp = (0 != (x & (1 << y)));
      for (i = 0; i < N; i++) {
      if (tmp) f(i);
      else g(i);
      }
      }

      This is something the compiler definitely can do. It's not quite the same as what you wrote, because I have not factored in and duplicated the 'for' loop, so I'm still performing an "if" each time. Is this slower than your transformation? Are you sure? Most current CPUs (including processors like the ARM series, designed for embedded applicaitons) include predicated execution. Combined with appropriat pipelining, that means that the extra "if" in there may require between 0 and 1 extra CPU cycles, depending on how it's implemented. (The un-executed branch essentially becomes a NOP, but on many pipelines, you have to incurr a NOP-equivalent penalty when branching back to the top of the loop anyways. Thus, you get one instruction "for free" at the end of any loop, which goes to waste if it's unused.)

      On the other hand, duplicating the "for" loop makes the size of that part of the code larger, let's say by 3-6 instructions - a handfull of bytes. Suppose this section of code is embedded in another loop which is run a lot. If you're unlucky, these extra few bytes may just push the code segment over the size of your instruction cache. Refilling the cache could waste hundreds of clock cycles.

      What's the point of all this? Well, first of all, it is possible for compilers to do the transformation in your example. That transformation may not be done by all current compilers (I don't know), but it will not always improve the code quality. All modern compilers can, however, perform a similar transformation, which can may result in an improvement which is slightly less than, the same as, or potentially better than your example. If you really want the best code possible, use a compiler that can accept and make use of profiling information. If the prof

    2. Re:Get the answer for yourself!! by Anonymous Coward · · Score: 0

      Obviously, it depends on what f and g are. When they are cos and sin, my compiler figures it out. Here's the pseudocode it generates when N is 1000 (before translating to assembly). Note: I had to add a return value so that it didn't convert the entire function into a noop.

      h(int, int)(x,y)
      __48 := 0.0
      if (0 != (x & 1 << y)) then
      i := 0
      do
      i += 1
      __32 := cos((double) i)
      __48 := __32 + __48
      while (i != 999)
      else
      i0 := 0
      do
      i0 += 1
      __39 := sin((double) i0)
      __48 := __39 + __48
      while (i0 != 999)
      endif
      return(__48)

    3. Re:Get the answer for yourself!! by Xyrus · · Score: 1

      "Seriously, if you don't know how to get the answer to the question for yourself, then you don't deserve to know the answer."

      Damn, I'd hate to be your kids.

      ~X~

      --
      ~X~
    4. Re:Get the answer for yourself!! by Anonymous Coward · · Score: 0

      Decent compilers are generally pretty amazing at doing optimizations like common subexpression elimination, loop unrolling, loop invariant hoisting, strength reduction (ie turning array accesses with an integer variable into pointer manipulation) partial redundancy elimination, arithmatic reassociation (for integers but not floating point)... Most of these are years old and gcc has done most of these for about as long. And compilers only get better whereas hand-tuned code would need to be re-tuned for optimal performance with each new micro-architecture.

      gcc has traditionally been weak at doing "scheduling" to get the best performance out of tight inner loops whereas icc and IBMs compiler kick the crap out of super tiny tight loops by handing them to the CPU in just the right fashion (top of loops are aligned on a cache boundary, etc). Much of this stuff requires pretty good knowledge of what happens inside the CPU however, which is why you and the guys who work on GCC can't do it as well as the guys who make the chips (though experimentation can pay off here off course).

      The place where C compilers usually have to throw up their hands is when you access memory or take the address of a local variable. Because I can cast anything to anything in C, you can't even be sure that accesses to an int array and accesses to a char array won't conflict! If you have a single array though and otherwise only access local variables that you never take the address of, you will find the compiler generally does a better job than you would do. At one job I both worked on the compiler(s) and hand-coded assembly and I can tell you that it was hard to beat the compiler especially for a large procedure.

      A type safe language can allow the compiler to do way more of these kinds of optimizations (but Java and the current crop of object oriented languages generally add other inefficiencies like method calls so they don't soundly beat C). Even when the compiler can't figure things out, out of order machines (practically all modern CPUs) can just assume that certain reorderings are legal and undo bad decisions later if they are detected later.

      Procedure calls are *generally* bad for the optimizer (most treat them as big boundaries where nearly anything can happen) but even this isn't always so, especially when you are working on an x86 that has limited numbers of registers and blindingly fast access to stack variables. Switch statements sometimes cause problems but certain idioms are handled well by the compiler so these aren't such a big deal. Unaligned accesses make CPUs very unhappy so make sure everything is aligned. You may want to manually order the elements of a structure to make it the most compact and the most aligned though if parts of it are accessed together and it's bigger than a single cache line, you may want to order it based on that.

      Many programs spend way too much time and waste much space with malloc and free so make sure you have good versions of these important functions.

      Compilers generally are pretty shy about unrolling loops because this explodes the memory footprint and a single cache miss is far worse than 50-100 unnecesary instructions! But if you profile your code, take the bits that need the most speed and compile them seperately with the right optimizers flags, you'll get the kind of code you want without anywhere near the effort.

    5. Re:Get the answer for yourself!! by Anonymous Coward · · Score: 0

      Your example is total nonsense.

      Compiler optimizers don't see x and y, much less (0 != (x ...)) as shown. They see things like:

      R1 - 0
      R2 - (arg1) ;; x
      R3 - 1
      R4 - (arg2) ;; y
      R5 - R4 shiftl R3 ...etc. All the optimizer has to do is color registers as loop invariant or not. Like this:

      R1 is invariant because it's constant. R2 is invariant because it's a passed-in argument which is not changed in the loop. R3 is invariant because it's a constant. R4 is invariant because it's a passed-in argument which is not changed in the loop. R5 is invariant BECAUSE R4 AND R3 WERE INVARIANT....

      This is absolutely trivial to code using basic lattice-based optimization methods.

  284. No code is real fast by ubergeek65536 · · Score: 1

    Most modern compilers know more tricks than even a hardend developer. One places where you will still find great performance gains is in the algorithm design. A slow quick sort will most likely be far faster than hand tweaked asm code any day. I was once told "The best code is no code. It's easier to read and runs a lot faster." Think at the algorithm level and let the compiler do the rest.

  285. optimisations - profile, both are clear by Anonymous Coward · · Score: 0

    I find both if (!p) and if (p==NULL) (almost) equially readble, the later - more error proun, and 'should' be written as
    "if (NULL==p)" to avoid accidental assignment. A bit hard to believe a 10 years C programmer would find if(!p) 'less readable', unless not actually reading other people's code.
    As for optimisations - is such cases - what's the problem? just look at the assembly output. In your example - they should yield 100% the same, since they both cmp to zero.
    In any real-world case - there's two tips:
    * profile! optimise only where critical
    * know thy processor, (for example in most counting downwards in loops in more 'efficient') - ofcourse - that's only important if you're doing time critical work.
    * get to know the compiler, compile small examples, look at the output, I remember getting to know GCC vs Watcom, we did alot of testing and profiling these days... combine with the last point, it's usually easy to predict in simple cases, in others - where it matters - drop into the ASM, and take a peek.

  286. Re:Clear Code - Boeing by gardyloo · · Score: 1

    Being that the bathroom isn't flight critical that code was probably only done to DO-178B Level E or maybe D. The software for flight critical components like displays and flight controls is scrutinized much more heavily.

    Oh, swell. So the display telling me that the bathroom is free is more critical than turd-dumping optimization?

  287. Never do (x == y) by zapatero · · Score: 2, Funny

    Oh you are so right. And as a corrolary never do if (x == y), because with both sides being variables one day you'll write (x = y), and (y = x) wont save you.

    The recommended way for (x == y) is
    if ( log(x) == log(y)) All the real good programmers that read magazine articles are doing this.

    And anyway, real numbers are more precise than integers. So in the case of x and y being integers its more precise using the log of the value.

    Never mind that gcc since 2.96 can issue warnings (or error with -Werror) and that languages like Java don't even allow assignments inside if(...), it's still good to practice this sound magazine article advice.

    In fact never program. Because one day you'll enter a typo, and you might have a bug, and so you should never program.

    1. Re:Never do (x == y) by antispam_ben · · Score: 1

      The recommended way for (x == y) is
      if ( log(x) == log(y)) All the real good programmers that read magazine articles are doing this.


      If either x or y is negative, this gets evaluated as a complex number and slows down execution. And of course in ths case it's the programmer, not the progam, that should be executed.

      In fact never program. Because one day you'll enter a typo, and you might have a bug, and so you should never program.

      Executing the programmer would insure that the programmer never makes a typo or bug.

      --
      Tag lost or not installed.
  288. Let the optimizer do its job by SamuraiiProgrammer · · Score: 1

    I've been C programming for 22 years or so. For at least the last 12 of that compilers have been smarter at optimization than I am. That's assuming you use a good optimization setting, of course, and you code honestly. A good optimizing compiler can do things that aren't really feasable in C source.

    There's a strong temptation to try coding assembly language in C, e.g. coding C with an eye to what the code generator will do. The problem is you end up losing track of the algorithm. If you really need assembly code, then go ahead and do it. There are ways with all the compilers to insert direct assembly. Good reasons are the need to use an instruction that just won't be generated by a C compiler (put something in THAT segment register) and a need to absolutely control the sequence and timing of instructions (typically related to I/O),

  289. Don't forget indexing by ebyrob · · Score: 1
    i, j and k can be used for indexing as well as loop counters.

    For example, if you've ever read c code for efficient string in string searches, you'll probably see 1-2 levels of nesting in a couple of places with 4 or more index variables (often i,j,k,l,etc) and several arrays. These are 20-40 line functions encoding mind-warping ideas that no length of variable name is really going to make you understand... (And if you think you're going to refactor Knuth_Morris_Pratt to make it "better" you've got a serious ego problem even if you have god-like genius and programming acumen)

    Personally I see nothing wrong with using short variable names in small functions (say 20 lines or less). In fact, I've read several times that when interviewing potential developers short variable names as loop indices (particularly for small loops) is a sign of an experienced developer.

    Basically, someone who's written millions of lines of code in a language isn't going to bother wondering how readable the following is:
    for( int i=0; i<20; i++ ) {
    /* do something for each i */
    }
    or even this:
    for( int i=0; i<MAX_ROWS; i++ ) {
    for( int j=0; j<MAX_COLS; j++ ) {
    /* do something for each item in table */
    }
    }
    They're just going to "bang it out". Further, they're going to realize that they can easily re-use pieces of their code if it tends to use simple and consistent variables... (Kind of like how physicists re-use the same variable names over and over to cement understanding and benefit re-use)

    Now... using 'i' as a class, module or global variable? That should revoke at least one of your 10 finger keeping privileges.

    Bottom line: The one thing that really distinguishes understandable code from code that has to be thrown out is the top-down documentation. This breaks down to project/sub-project/module/public function/protected function/line level. The distinction in readability between 'NULL==ptr' and '!ptr' is meaningless if the public function they reside in doesn't have proper header comments.
  290. Ideas contributed here & tricks by Anonymous Coward · · Score: 0

    Agreed. modern compilers are very intelligent & offer many options (especially C/C++ ones).

    I think you can do profilers, or "make your own" with hi-res timers ticking off time each proc/function etc. takes & do some hand-tuning if needed too identifying time-consuming areas better or ones that don't immediately stand-out & jump at you (like loops possibly etc.)!

    Using Shr 2 vs. div calls is faster, this I have found out when doing division for instance & iirc.

    Another one that alot of folks "put down"? Is to use SHORT STRINGS vs. std. Win32 long variety.

    Why? Well, let's say you're writing a program that vectors thru your directories/folders, which ARE limited to 254/255 character array string lengths... just humor me on that example, it's an off-the-top of my head one!

    The advantage of the "Short" strings is that they can be allocated on the stack and thus
    have no memory manager overhead, pointers etc associated with them!

    That makes them simple to use.

    (And many strings *are* less than 255 chars, always, such as folder/directory & file
    names, even under Fat32/NTFS.)

    Maybe some of you guys will dispute that & I hope you do because it's not like I cannot be wrong, but it does make sense!

    Those 2 tricks are some of what I have done that seem to work as some examples of fine-tuning via hand you can do above & beyond compiler options for optimizations.

    (Nothing as you guys mentioned, beats good reasoning, architecture, and algorithm/engine design though. Use the noodle God gave you I guess!)

    APK

    P.S.=> I like what I read here though, good stuff. I like Slashdot alot for that in fact, alot of "brainies" come here & it's one of the few spots online I can stand to learn something NEW every day which is great.. apk

  291. Re: code never lies? by Anonymous Coward · · Score: 0
    How do you know if your code is lying? Check the header files.

    #define MOVE_LIPS() do { lie (); } while(0)

    Sorry. I hope I didn't offend any men, women, used car salespeople, lawyers or corporate executives! *ducks*

  292. My Approach by Javagator · · Score: 1

    Here are some rules of thumb that I apply (for what it's worth).

    Minor syntactic things like using !p verses p == NULL rarely make a difference. I try for clarity, modularity, and simplicity when I code. This comes in handy when you have to optimize latter. Few people know what code a compiler generates, and even fewer know what kind of code will be generated for version 3.0, or for the next generation of processors.

    Profile your code. You will often be surprised where the bottlenecks are.

    Consider using a better algorithm when you optimize. As a corollary, know the strengths and weaknesses of various algorithms and data structures. Fortunately, this is a lot easier than understanding compiler generated code.

    I/O considerations can result in a big win. Try to minimize I/O by caching. Also, writing out large array of items will be much faster that writing out one element at a time. Serialization in object oriented languages such as Java and C# can have some quirks. For example, serializing an array of Points can be put slower than serializing an int array of X values and an int array of Y values.

    When possible put your objects on the stack, instead of the heap. Besides being more efficient, it also is less error prone with regard to memory leaks and pointer errors.

  293. C# by prockcore · · Score: 1

    take 'if (!ptr)' instead of 'if (ptr==NULL)'

    Once again, C# wouldn't allow the first, only the second. That's because you cannot implicitly cast things to boolean.

    it also won't let you screw up the second and say if (ptr=NULL) on accident.

  294. gcc compiles these to the same thing by Admiral+Ackbar · · Score: 1

    According to some test compiles I did, gcc compiles both constructs to the same assembler output:

    cmpl $0, -4(%ebp)
    jne .L2

    I vote for readable code.

  295. Huh by clarkcox3 · · Score: 1
    As a simple example, take 'if (!ptr)' instead of 'if (ptr==NULL)'. The reason someone might use the former code snippet is because they believe it would result in smaller machine code if the compiler does not do optimizations or is not smart enough to optimize the particular code snippet

    Sorry, but any developer that thinks that there'll be a significant difference in the code generated by either statement is either using a compiler written by a child, or is a moron.

    --
    There are no tiger attacks in my area and it's all because this rock I'm holding keeps the tigers away.
  296. Trusting the compiler will become very important by Mr_Huber · · Score: 2, Interesting

    Consider all the hype last week about the cell processor. Here is a processor in which the CISC optimizing portions have been removed, trusting the compiler to create pre-optimized code. The cell processor will run this code blindingly fast and with no modification. The compiler must be a smart optimizer. IBM, Toshiba and Sony are betting a lot on a smart optimizer. I'm guessing they won't be disappointed.

    Further, consider the Parrot system to be used by Perl, Python and Ruby. There's a strong similarity here to the cell system. All three languages are to be compiled to a common register-based representation. That representation is to be optimized by the compiler before execution. They chose this model because w we have decades of research on optimizing code for register based computers (as opposed to Java's stack based computer).

    In short, some very large, very important projects already have a lot of faith in these optimizers. They are not going away. I suggest the best approach is to work with them.

    So how do you cooperate with your optimizer? Write cleanly and clearly. Don't try to outsmart the optimizer, because if you do so, your code will most likely be slower, not faster. And don't do any work until you need to. Write the project correctly and clearly, then profile. If you need to modify things, then you have a working baseline to compare your optimizations with.

    Finally, when you get the faster version, check it in, then refactor the design to something reasonable, rechecking the speed as you do so. Ideally, for a small performance hit, you can end up with fast, efficient and easy to maintain code.

  297. Re: third point by Anonymous Coward · · Score: 0
    Third: Apply minimum algorithmic complexity. If you can use a hashmap instead of a treemap use the hash version it's O(1) vs Olog(n). Use quicksort for just about any kind of sorting you need to do.
    Do I need to remind you that growing your hashmap at log-sized intervals results in O(log n) average insertion? Or that an improperly sized hashmap or one with a poor hashing function has O(n) lookup times? If you're unsure of the exact data you'll be inserting, choose a treemap. It's always O(log n), and that's a heck of a lot faster than the O(n) worst case of a hashmap.
  298. Obey the rules by ruurd · · Score: 1

    Rule #1: Do not optimize!
    Rule #2: Do not optimize! Yet!

    In other words: hand optimizing code is a Bad Thing (TM). It is taking time better spent making your code neat and understandable and well documented. It is obfuscating your code and making it hard to maintain.
    Last but not least, it is an unfounded approach to optimization. If it turns out that the code needs optimization, use a profiler and then optimize where needed. Annotate the optimized code with the original one and a clear warning you have been optimizing that piece of code.

    --
    ruurd
  299. 's/&/|/' by Anonymous Coward · · Score: 0

    (n/t)

  300. Strawman alert... by Anonymous Coward · · Score: 0

    Damn if the didn't raise an army of them!

  301. "Very few compilers" by bani · · Score: 1

    do you know which ones will?

    1. Re:"Very few compilers" by Anonymous Coward · · Score: 0

      I bet the answer is "zero", but the OP has trained himself to not make blanket statements (people will pounce on those, especially on message boards), so he said "very few" instead.

  302. it's a standard idiom by Xtifr · · Score: 1

    The word you're looking for is "idiom". And I agree, (!ptr) is idiomatic. It's even introduced as a standard idiom in many C reference works and style guides. There are plenty of ways to abuse the sytax of C in order to produce unclear or unreadable code, but this is not one of them. If you don't instantly recognize the idiom, I don't think you can claim to even qualify as a novice C programmer yet. You might, just as fruitfully, claim that curly braces are not as clear as "BEGIN" and "END" for marking blocks. That may even be true - if you're completely unfamiliar with C (or its many cousins).

  303. Pedant point by colinrichardday · · Score: 1

    The program's speed is directly proportional to how often a function is called? So the more the function is called, the faster the program?

    Or is it the execution time that is proportional to how often the function is called?

  304. Re: third point by MSBob · · Score: 1

    It's true but it's just a nitpick in my argument. What I said is make sure you're using the most optimal algorithms for your circumstances. Of course, in some cases tree lookups will be faster. Other things to consider are whether inserts or reads will be more frequent etc. The point is, always pick what makes the most sense for your dataset. Most developers tend to just pick whatever came with the standard library or even worse always use DA ARRAY that came built into the language.

    --
    Your pizza just the way you ought to have it.
  305. Re:Clear Code [NOT] by Anonymous Coward · · Score: 0

    No you have it backwards. It's not the ultimate boolean logic that is important but your intention.

    Zero and one are often used to mean (0 == FALSE, 1 == TRUE).

    Zero and one are also used to mean (0 == SUCCESS, 1 == FAILURE) unless you're using the WIN32 API, in which case the opposite is usually true!

    In a language like C, where there is no native boolean type and which allows you to easily break abstraction barriers, it is especially important say whether you're testing for non-zero-ness, true-or-falseness, or something else entirely.

    What is the intention of the following statement?

    if (!x) { ...
    }

    Is it

    if (x == FALSE) ... (equivalent to) if (x != TRUE) ,

    OR

    if (x == 0)... (NOT equivalent to) if (x != 1) ?

    The best thing to do is to be explicit.

    If x indicates success or failure, then x should be explicitly tested against SUCCESS or FAILURE (which should be macros (better) or enums (better still)).

    If x is really an integer type then it is better to test against some integer value.

    Use if (strcmp(a,b) == 0) instead of the horrible if (!strcmp(a,b)

    Prefer if (x == NULL) to the ugly if (!x)

  306. should you be optimizing? by nerdsv650 · · Score: 2, Informative

    A couple of points.

    First off *any* compiler will make that particular optimization.

    You should only think of instruction level optimization when you know with certainty that it will pay off, for example because you've run your code under a profiler and found the areas where it will actually make a difference. Once you've found the (probably tiny) areas where optimizing actually helps, do whatever it takes, and document your reasons as well as your methods.

    You can always ask your compiler to output assembly and look it over, if you aren't fluent in your proc's assembly you probably shouldn't be trying to out-optimize the compiler anyhow.

    That being said, "if (!ptr)" is legitimate and bears a different connotation from "if (ptr == NULL)", at least in my mind. One is truth, the other is zeroness. In some cases the former is actually the more obvious test. There are also cases where compactness yields more readable code because the whole idea fits in a space easily acquired at a glance, for example, "if (structp && structp->member == VAL)" is natural and obvious to anyone who's been at this for any amount of time.

    All of this, of course, IMO.

    -michael

  307. (!ptr) vs. (ptr==NULL) rationale by Krellan · · Score: 1

    Problems with using (ptr==NULL):

    1) The == can easily be mistyped as =, introducing a nasty bug into your program.

    It's harder to read, but when comparing with the == operator, I try to make sure the value on the left isn't a lvalue. For instance, (42==lue) instead of (lue==42). That way, if I mistype == as =, the compiler catches it, because you can't assign to something that's not a lvalue. Unfortunately, this won't work when both sides are lvalues.

    2) The NULL resolves to a constant (0), which might get inserted into your program's code and used during the comparison. An unnecessary size bloat.

    It's the same reason you want to write a loop as for(;;) instead of while(TRUE): you avoid the insertion of the TRUE constant, and unnecessary comparison thereof, into your program.

  308. Is it all done at runtime anyway? by JLeslie · · Score: 1

    Aside from what others have mentioned about choosing the right algorithm in the first place, it seems that with the way a lot of hardware optimizes stuff these days (eg intels out-of-order execution) that pre runtime optimization should be less of a focus. I seem to remember reading that the latest CPU's can consider many hundreds of instructions when reordering. At this level, does what the compiler do even matter?

  309. Example: do _not_ optimize yourself! by Anonymous Coward · · Score: 1, Interesting

    I recently wrote some code to transform an image (proof-of-concept, no filtering) according to a mapping table, like this:

    unsigned char *origimg = malloc (width * height * 3);
    unsigned char *imgdest = malloc (horpix * vertpix * 3);
    unsigned char **mapping =
    malloc (horpix * vertpix * sizeof (unsigned char *));

    with some formula to morph the image, getting a pointer to the input pixel for every output pixel:

    mapping[y * horpix + x] =
    origimg + somey() * width * 3 + somex() * 3;

    Now the interesting part. To do the mapping itself (repeatedly, think movie), this looks about the worst you can come up with:

    for (y = 0; y < vertpix; y++)
    for (x = 0; x < horpix; x++)
    {
    imgdest[(y * horpix + x) * 3] = *mapping[y * horpix + x];
    imgdest[(y * horpix + x) * 3 + 1] = *(mapping[y * horpix + x] + 1);
    imgdest[(y * horpix + x) * 3 + 2] = *(mapping[y * horpix + x] + 2);
    }

    YET: Try ANY hand-optimization that performs the exact same function, and gcc-2.95.2 -O9 -funroll-loops on i386 will produce SLOWER code! Even having a single var for (y*horpix+x) is SLOWER! If you don't believe me, try it. I did, and I was _very_ surprised.

    The fastest version I ended up with actually optimizes differently by not copying 3, but 4 bytes at once:

    for (y = 0; y < vertpix; y++)
    for (x = 0; x < horpix; x++)
    {
    *((unsigned int*) (imgdest+((y * horpix + x) * 3))) =
    *((unsigned int *) mapping[y * horpix + x]);
    }

    But this is only a few percent faster than the original, and again, do NOT optimize further!

    -- JAB
    (Code donated to the public domain)

  310. no need for programmer optimization by grumpyman · · Score: 0

    The programmer should not need to worry about optimization. Like human language, when it is simplified and reduced to two words 'yaba' and 'daba', the interpreter should know what we are talking about.

  311. Usually worse by hacksoncode · · Score: 1
    I would say that my opinion is that in modern times, humans will usually (though not always) be inferior to the compiler at performing local optimizations.

    The only kinds of optimizations where humans have the edge are largely global ones. For example: protocols for optimizing thread usage and mutex exclusion.

    While I'm unwilling to extend this confidence to all embedded compilers, I'm largely willing to extend it to those embedded compilers based on gcc.

    I think the reason to optimize code in the source is in situations where it will actually *improve* the readbility or maintainability of the code, when taking into account comments, variable names, and other structural means of aiding this.

    Every line of code is a potential bug.

  312. Re:Clear Code - don't optimize while writing it! by Anonymous Coward · · Score: 0

    >> Correction: Some compilers aren't stupid. Others are. I used to rely on compilers to optimize my code. Metrowerks Codewarrior taught me otherwise.

    Interesting. My old CodeWarrior 4.0 compiled both examples in the article ("if (!ptr)" and "if (ptr==NULL)") to exactly the same object code -- for both 68k and PowerPC.

    The point is, if you're worrying about this kind of syntax issue, don't. The grandparent post is right; don't even begin to think about optimizing until you've already written working, clear code.

  313. it was more typing efficiency/style than anything by that+_evil+_gleek · · Score: 1

    if (!ptr) vs ( ptr == NULL ) is more of style thing , !ptr is shorter, so efficient for the coder
    who is typing it in, then that explanation of style got confused with program efficiency.
    Also less shifted characters, 1 shifted character the ! vs 4 shifted chars.

    Also, with (ptr == NULL) one can mistype and do (ptr = NULL ) instead, can't make that mistake with
    if (ptr) or (!ptr). Though, you can try if ( NULL == ptr ).

    As far as optimization, I don't know as the negation adds a operation has the cmp to zero would, but I believe optimizations on it would be able same.

  314. Three things for open source code by fitterhappier · · Score: 1

    1) Make it go
    2) Make it readable
    3) Make it fast

    If you move 3) anywhere else in the list, the project will suffer. Once you've got the project working and have people reading the code, you'll begin, in my experience, to get contributions that help with 3). Writing code that attempts to outsmart or to pass hints to the compiler can easily lead to a violation of the goal order above.

  315. The Solution by Anonymous Coward · · Score: 0

    I maintain that the only true solution to optimization is to choose the right language to work in. If you truely want a language in which confusion is simply not a problem, try this. It resolves the "if (!ptr)" vs "if (ptr == NULL)" argument nicely.

  316. Once you decide to optimize... by LoveMe2Times · · Score: 3, Insightful
    I'm going to presume that you've *already* picked a reasonably effecient algorithm, 'cause otherwise there's no point. Second, I'm going to presume that you've already run the profiler, so you know which lines of code are important.

    Here's my "guide to optimizing":

    1) Are you disk I/O bound? You might need to switch to memory mapped files, or you might need to tweak the settings on the ones you have. You might need to use a lower level library to do your I/O. Many C++ iostreams implementations are slow, and many similar libraries involve lots of copying.

    2) Are you socket I/O (or similar) bound? If so, you may need to rewrite with asynchronous I/O. This can be a PITA. Suck it up.

    3) Are your threads spending all their time sitting in locks waiting for other threads? One, make sure you're using an appropriate number of worker threads optimized by the number of CPUs the host has. If you've already got the right number of threads, this can be a really tough decision. Presumably, the threads are helping your program readability, and trying to rework things into fewer threads is often a *bad idea*.

    4) Are you spending all your time in malloc/new/constructor free/delete/deconstructor? Maybe you need to keep things on the stack, use a garbage collector, use reference counted objects, use pooled memory techniques, etc. In the right places, switching from some "string" library to const char* and stack buffers can give a huge benefit. Make sure, of course, that you use the "n" version of all standard string functions (the ones that take the size of the buffer as an argument) to avoid buffer overruns.

    5) Are you spending all of your time in some system call? Like maybe some kind of WriteTextToScreen or FillRectangleWithPattern type of thing? For drawing code in general, try buffering things that are algorithmically generated in bitmaps, and only regenerate the parts that change. Then just blit together the pieces for your final output. Perhaps you need to rely on hardware transparency support for fast layer compositing. You might need fewer system level windows so you draw more in one function. Maybe you need to reduce your frame rate.

    6) Are you using memcpy as appropriate?

    If any of the previous items are true, you have no business worrying about the compiler. However, once you've gotten this far, you can start worrying about optimizing your code line by line.

    7) Since you've gotten this far, the line(s) of code you're worried about are all inside some loop that gets run. A lot. They may be inside a function that's called from a loop too, of course. So, a few things to consider. A) You may need to use templates to get code that is optimized for the appropriate data type. B) You may need to split off a more focused version of the function from the general purpose function if it's also used in non-critical areas. This has negative maintainance ramifications. C) Do the bonehead obvious stuff like moving everything out of the loop that you can. D) Look at the assembly actually generated by your compiler. If you're not confortable with this, you have no business doing further optimization.

    After looking at the assembler, then you'll know if the following are important. In my experience, they are.

    1) Change array indexing logic to pointer logic:

    MyType stuff[100];
    for( int i = 0; i < sizeof(stuff) - 1; i++)
    {
    stuff[i] = abs(stuff[i+1]/PI);
    if (stuff[i] < 0)
    stuff[i] = 0;
    else if (stuff[i] > maxval)
    stuff[i] = maxval;
    }

    can change to:

    MyType stuff[100];
    for( MyType* ptr = stuff; ptr < &stuff[98]; ptr++)
    {
    *ptr = abs(*(ptr+1)/PI);
    if (*ptr < 0)
    *ptr = 0;
    else if (*ptr > maxval)
    *ptr = maxval;
    }

    This eliminates lots of redundant addition. All of those stuff[i] = val type of statements tend to generate:

    mov

    1. Re:Once you decide to optimize... by cimetmc · · Score: 1

      I'm sorry, but I have to fundementally disagree with the optimiztations you gave at the end of your message. Unfortunately, for generations, C programmers have been tought to use pointers to access arrays, and this simply because for a long time, C compilers were not really optimizing compilers and so the programmers where always thinking in the code that the compiler would generate. However nowadays, this is no longer true, and using pointers to access elements in an arry is actually a very bad idea because it prevents the compiler from doing some kind of optimizations as you "hide" the fact from the compiler that you are just accessing a single array and you make it difficult for the compiler to track alias information and do loop unrolling. I tried your code with GCC 3.4.2 both with integer and floating point data types, and in both cases, the compiler did not generate code to make complicated address calculations, but instead used the indexed addressing modes of the i386 instruction set to directly address the array elements. In this particular case, this results in code more or less equivalent to the pointer code. However the situation would become different with a loop that would have to access 3 or 4 arrays at the same time. If you used different pointers for each array, a registry starved processor like the i386 would not have enough registers to hold all the pointers and so some pointers would be kept in memory and would have to be reloaded to a registry each time the array would have to be accessed. However using the indexed addressing modes of the i386, a single register would be enough to address the elements in the different arrays, thus leaving enough other registers for the actual calculations that might be done in the loop. Marcel

    2. Re:Once you decide to optimize... by Anonymous Coward · · Score: 0

      And by using inline assembler, you make it abundantly clear to any casual observers that this code is not-to-be-messed-with.

      And not to be used on another system with a different video card? What kind of sadist are you? Give me one example where spending hours thinking how to do something in inline assembly has made business sense (versus inflating your ego of "look at that, I'ms a doin assembly!").

    3. Re:Once you decide to optimize... by LoveMe2Times · · Score: 1

      Aha, you sir, deserve a cookie :) You tried it one way, looked at the assembler, tried it the other way, looked at the assembler, and voila, make an educated decision. I've not optimized with GCC for a while; I've been a VC++ monkey lately. At any rate, it does seem to depend on specifically what you are doing with the array elements. I haven't figured out exactly what the compiler is doing; sometimes it can tell that the index hasn't changed between references, perhaps depending on the complexity of the expression. Sometimes it can't. I can tell you this, though: this kind of optimization has been the most common for me the last few years.

      And yes, figuring out how to work around registry limitations is often the focus of further optimization. If GCC is being smart enough to set up segment selectors, that's great. You still only get 4 segment registers, though (unless you use the stack segment). At any rate, you make me want to go toy with the latest GCC.

      Either way, if I look at the compiler output and think, "That's stupid," then I'll use inline assembler to tweak it and make the whole issue moot.

      Thanks for your insightful response! (I'd mod you up, but alas, I already posted :)

    4. Re:Once you decide to optimize... by LoveMe2Times · · Score: 1

      Well, ok, admittedly, I have not actually programmed the the graphics coprocessor. Yet. I've thought about it, though, and I will do more research into it. I probably stated things a little forcefully in my first message: I didn't mean you should *always* be programming the graphics coprocessor, just that if you're doing this level of optimization, you should be aware of that as a possibility.

      Now, about spending hours doing inline assembly: if you read my post, you'd notice that it was the last thing in the list. Presumably, you've already A) optimized the algorithm, B) profiled, and C) taken the low hanging fruit. For whatever reason, it's still not good enough. At this point, you've already invested (likely) several days to "fixing" performance. You've studied the assembler that the compiler is generating. Now, you can either A) bend over backwards trying to get the compiler to apply better optimizations, or B) do it yourself. A) has the disadvantage that it's very compiler-specific sometimes, and somebody might innocently change the code, wrecking performance. B) has the disadvantage that it is processor family specific, but I see this as no worse than being compiler specific (in fact, it's often better). They both require a certain kind of expertise, double checking with the reference manuals, and maybe a little trial and error. Once again, I like the inline assembler because it doesn't change when a new compiler comes out. You don't have to worry until a new processor becomes common, and even then, only if you've carefully tweaked pipeline parallelism or cache behavior. And of course, you have this problem anyway, except you're depending on the *compiler* people to optimize for the new proc better.

      Let me put it this way: the compiler optimzation is crucial for all the millions of lines of code that you're *not* going to look at. Once you've run the profiler, though, and found those 20 important lines, don't hesitate about taking things into your own hands. And if it wasn't worth it to spend a couple days on those 20 lines of code, you wouldn't have started this exercise in the first place.

      Oh, and one last thing: inline assembler remains even in debug mode, when the compiler will obviously not be applying aggressive optimization. This can make debugging the rest of the application much more pleasant!

    5. Re:Once you decide to optimize... by r00t · · Score: 1

      The "restrict" keyword can help, particularly when
      used in combination with const.

  317. Use of the Scientific Method in Computer Science? by antispam_ben · · Score: 1

    (I'm tempted to make some racist crack about the submitter, but I've met lots of programmers, from every corner of the planet, with similarly dimwitted notions about what happens to their source code when it is submitted to the compiler. Obviously, the general quality of computer science education (or computer science students) is depressingly low the world over.)

    I don't recall a compiler that didn't have assembly-language output file generation as an option, but if there were, one could always disassemble the binary object code. So, it's easy enough to do this Computer Science experiment:

    Hypothessis:
    This piece of code when compiled will execute faster and/or be smaller than that equivalent piece of code.

    Test:
    Compile both pieces of code, measure code size and execution time.

    Conclusion:
    Differences were found to be nil or inconsequential.

    From there it's a small step to this, which can result in a giant leap in realization (while you're at it, mod me redundant):

    Hypothesis:
    Using the most appropriate algorithm makes a larger difference than doing micro-optimizations.

    Test:
    Do a few projects with well-thought-out algorithms and don't try to micro-optimize.

    Conclusion:
    Wow, what a difference!

    --
    Tag lost or not installed.
  318. "All the warning they need" by Anonymous+Brave+Guy · · Score: 1
    My rule is if the programmer can't figure it out, they shouldn't be working on my code.

    I've spent roughly a year working on my current assignment. The first six weeks of that were developing the feature that motivated the work; that was almost exactly what we estimated. The next ten months were fixing all the regressions, essentially clearing up the mess made by people like you who left special cases and witty comments like your example lying all over the code. I have figured it out, and in the process I've fixed a very large number of bugs, but if the original developers had done a competent job in the first place I wouldn't have had to waste nearly a year cleaning up after them.

    --
    If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
    1. Re:"All the warning they need" by Greyfox · · Score: 1
      Oddly enough, the only person ever to ignore that rather blatant warning was someone who really DIDN'T know what he was doing. He didn't last long though. Spent most of his time bitching about not being able to access his external POP mail from behind the firewall and stuff like that. Probably the only code change he ever made was to that line. I actually made a point of looking through the version control records and making sure that he hadn't done any major damage to our code base.

      Actually 5 lines earlier in the code. at the start of the loop, I say "Some of these functions modify bar and others don't. Don't change the &bars to bars or vice versa unless you really know what you're doing." We actually did have some good design reasons for doing it and were going to try to depreciate the module later anyway.

      I have to admit though, that I did get a sadistic chuckle from the site that suggested having variable names "swimmer" and "swimner," ideally with one in the global namespace...

      --

      I'm trying to teach myself to set people on fire with my mind... Is it hot in here?

  319. for_each by Anonymous+Brave+Guy · · Score: 1
    A more-concise, and potentially more clear solution would be: for_each(foo.begin(), foo.end(), ...).

    Which would be lovely, if C++ also supported first order functions so that the STL algorithms requiring functors could be written in a useful way. As it is, you have to mess around creating small helper functions well away from where they are used, or worse start involving function objects, to achieve what should be a trivial effect. The closest you can get on an enlightened project using a modern compiler is one of the lambda-style libraries, and even those are a long way short of the basics of a serious functional programming language.

    I think C++ has a lot of practical merits, and I'm all for using the right tool for the right job, I just find that a simple for-loop is almost invariably a cleaner solution than any standard library algorithm that requires a functor. for_each is a particularly bad example, because even the literature isn't clear on what it's intended to do, and whether things like mutating effects are allowed (and will continue to be so in future).

    --
    If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
  320. Programmer vs Compiler by Anonymous Coward · · Score: 0

    Regarding GCC, at least (PowerPC version), it doesn't do too good a job with code such as:

    a = b = c = 10;

    If you look at the code produced, it is (in effect):

    c = 10;
    b = c;
    a = b;

    With all the memory loads/stores that would suggest. You get much better code by writing:
    c = 10;
    b = 10;
    a = 10;

  321. No, no, no! Semantics... by Catullus · · Score: 2, Insightful

    The grandparent poster was completely right. The implied meaning of "if (!ptr)" is "if ptr is not valid". The fact that NULL is equivalent to "not valid" is essentially irrelevant to understanding the statement.

    The key aspect - and the interesting thing - about coding style is that you are writing something for other humans to read. Everything you write contains hints to those humans about what you mean. Saying "a == NULL" is subtly different to saying "!a".

    Being able to read programs and pick up stuff like that is possibly something that takes a long time to learn, but (imho) it's very important. Code written by true experts is fascinating because of the way that they make the meaning of what they're writing clear.

    This is why (again imho) programming is an art, not a science.

    Incidentally - pointers are not references to data. They are data like anything else. Unless you understand this, pointers to pointers are fairly meaningless. Always remember: in C, everything is a bunch of bytes.

  322. Nothing to do with optimization. by argent · · Score: 1

    I would use if (!ptr)... if the pointer is being used in a way that its value is related to a true-or-false condition. That is, reating it as a boolean makes semantic sense at the "human layer".

    I would be utterly amazed if any modern compiler (say, any compiler released in the past couple of decades that wasn't a novice hobbyist effort) treated it any differently from if (ptr==NULL)....

    I don't think I'd use if (ptr==0) ..., even though I know that NULL is equivalent to 0 (and for eny modern compiler identical), because it doesn't make semantic sense in any situation I can think of... at least not off the top of my head. I would use if (ptr==NULL) ... where that made sense.

  323. Diagnostics did by Anonymous+Brave+Guy · · Score: 1

    In the general case (as opposed to the specific NULL case where you can just omit the explicit comparison entirely) most modern compilers will issue a warning message if you use assignment for equality where it is suspicious to do so (e.g., in a test condition for a control statement). Since the defensive coding style is also hideously hard to read even if you're fairly used to it, and is now mostly redundant, it's gone the way of most good ideas that have had their time.

    --
    If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
  324. Request for clarification by colinrichardday · · Score: 1

    A question about the word "may". Do you mean that it might not have the value 0xdeadbeef (but it might), or that it cannot have the value 0xdeadbeef?

    1. Re:Request for clarification by Anonymous Coward · · Score: 0

      Clearly, if you read the sentence before, it cannot have the value 0xdeadbeef. I suppose I should have said "It is not allowed to have the value 0xdeadbeef" so as not to confuse anyone.

  325. Basic misunderstandings by Anonymous+Brave+Guy · · Score: 1

    Please, please go and read the more informed posts about NULL above. In fact, please take the scarily large number of other posters in this thread who are horribly ill-informed with you.

    • NULL certainly isn't a void* in C++, and indeed it would be illegal to define it as such since this would prohibit many common pointer conversions.
    • NULL is a macro, and could never be typedef'd since it's not a type.
    • There is no requirement for NULL to be 32 bits normally or otherwise.
    • Your opinion about using NULL vs. using 0 is entirely subjective, and since NULL is typically #defined to be 0 anyway, your argument about letting the compiler do type conversions for you has no merit.

    YHBT. HAND.

    --
    If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
  326. Nice discovery... by Anonymous+Brave+Guy · · Score: 1
    Keep in mind that quicksort will always have a worst case performance of O(n^2); however, on average it runs about 10% faster than the fastest possible heapsort and mergesort algorithms, which are both O(log n). The main reason for using quicksort is the fact that it's 10% faster *on average* than the pure O(log n) algorithms.

    I'd imagine quicksort is probably also rather more correct than any O(log n) sorting algorithm...

    --
    If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
    1. Re:Nice discovery... by Anonymous Coward · · Score: 0

      Damn tpyos. O(n log n). *bow Anonymous Brave Guy*

  327. Optimization is bad, but by bill_kress · · Score: 1

    I really really like the if(obj) syntax. It seems so "logically cleaner" than if(obj != null) to me.

    It's the only thing I missed when I came to Java, but on the other hand, requiring that an if statement take a boolean has saved me trouble and never cost me anything, so I guess it's not worth it no matter how nice it feels.

  328. profile , profile, profile by Anonymous Coward · · Score: 0

    Write readable code first, make sure it's correct, profile it, and optimize the bottlenecks... try compiler switches first, before doing any extravagant code hacks.

    (Plus, its 2005... why are we caring about how many instructions if(!ptr) generates anyways? :P )

  329. Readability by EdMcMan · · Score: 1

    If other people are using your code, you should always write clear code as opposed to making your code marginally-but-not-really-noticeably faster.

    If you are so concerned about performance, do some profiling. There's no use saving pennies and then spending dollars.

  330. Compiler! (Uh, mostly.) by cgreuter · · Score: 1

    I'm not an optimizing compiler developer but I do work one desk over from one and I have grovelled through said compiler's output looking for bugs, so:

    In answer to your question, hand-optimizing your C code is worthless[1]. Modern compilers, even the ones without overly advanced optimizers, are able to generate more or less the same code for any of the sorts of differences you mention. Don't bother hand-optimizing.

    In fact, hand-optimizing can sometimes make your code slower. Optimizers are written on the assumption that the coder is trying to write clear, readable code without excessive cleverness and if you do hand-optimize your C code, you may out-clever the optimizer.

    The "correct" way to write efficient C code is:

    1. Write the program in C, making sure your code is correct and maintainable. Usually, it will end up being fast enough.
    2. If it's not fast enough, profile to find bottlenecks in the code.
    3. Try to eliminate the bottlenecks by using more efficient algorithms.
    4. If the algorithms are optimal and it's still too slow, try playing with optimization options. If the compiler offers unsafe optimizations, you may want to try those on your problem code (after first making sure your code doesn't violate any of the constraints imposed by them, of course).
    5. If it still isn't fast enough, get the compiler to generate assembly code for you and hand-optimize that.

    As for embedded systems, the constraint there is usually on code size instead of speed so embedded developers will often be very selective on which routines they machine-optimize. And because programmer time is cheaper than computer time in the embedded world, they'll typically hand-optimize the compiler output a lot more (assuming that they use C at all, which isn't a given).

    In general, C code is fast enough already, the compiler does an okay job for free and if you do need faster code, let the compiler take you as far is it will go first.

    [1] Er, okay, that's only true 99.9% of the time. You'll sometimes have cases where a particular C construct doesn't translate very easily to your architecture. For example, the post-increment and post-decrement operators tend to be troublesome when used in more complex expressions unless the architecture has a pre- or post-increment opcode.

    However, that sort of thing happens rarely and never in a portable way. The time to start worrying about it is when you've reached stage 5 and are grovelling through your compiler output trying to figure out how to improve on it.

  331. In comparisons, put the L-Value on the right by farnsaw · · Score: 1
    When doing a comparison like this (ptr==null) you should always put the L-Value on the right (null==ptr) so that when you make the mistake of using the assignment operator (=) instead of the "is equal to" operator (==) you receive a syntax error.
    if (ptr=null)
    {
    // This code changes the value of ptr to null
    // Since Null equates to false, this code NEVER runs.
    }
    else
    {
    // This code ALWAYS runs
    }

    if (null=ptr)
    {
    // However if you do it this way,
    // A syntax error is thrown on compile
    }
    --
    "Computer Scientists can count to 1024 on their fingers" (non-mutant, non-mutilatated, human computer scientists)
  332. Re:Code, Compiler and Optimization by omb · · Score: 3, Insightful
    As someone who has been in the industry for a long time:

    This issue is in like this,

    You need to understand the language, both syntax AND semantics you are using

    this ranges from the simple to mind-bending e.g. C++ (I am convinced that not even Bjarne Stroustrup understands this evil language);

    at that point you have two bi-furcations (a) interpreted languages eg Java, Perl, PHP and Python -v- (b) cpmpiled languages, and (c) finally DIY (do it your self) Assembler

    So: what does it amount to in practice? A) Rock Bottom, understand the architecture, including virtual memory, architecture and instruction set issues, read and understand the chip data sheet. Hard! See bottom line, architecture dependand code in Linux, bsd ...

    B) use 'gcc -S' and write the code in C, hand improve the assembler output, this is what I normally do, but you need to keep an open mind otherwise you miss things, I once took a compute intensive algorithm for the M68020 and made it run 10'000 times faster using this approach

    C)consider hardware optimisation; strictly price/performance.

  333. Re:Clear Code (FP pedant) by Steveftoth · · Score: 1

    but even that's not quite right.

    you should at least do a comparison like

    if ( var == 0f)

    so that you and the compiler are sure that you are using the right value for 0 (in floating point)

    And if you are concerned with fp error, then you should actually use a less then comparison like

    if ( Math.abs(var) THRESHOLD )

    where threshold is a very small number like 1E-20 or something (enough for your purpose). Since floating point calculations have error and it can build over multiple operations.

    http://www.dsprelated.com/showmessage/25885/1.ph p

  334. Once we have dealt with #1... by Anonymous Coward · · Score: 1, Interesting

    #1 of course is choice of good algorithm, hash structures, lookup structures, whatever.

    As an example, I had some terrain rastering program starting with isoheight lines to optimize. Some computer scientists had already optimized the searches, cutting the running time for jobs with in the order of 100000 line segments in half. From every raster point, searches were done in eight directions to find the next isoheight line, then a distance-weighted average was taken.

    The code had become unreadable with the optimizations and still ran a day. I decided to rewrite it, matching the data structures the other way round. Instead of going through the raster points and looking for the lines, I went through the lines and registered every of their crossing with the straight and diagonal grid (Bresenham). Then I sorted the grid crossings and worked out the stuff.

    It took me two hours of debugging after 10 days of implementation to find out why my program would exit unexpectedly after less than a minute. I finally got it. It was finished.

    So here is rule #1: design your algorithm well. Here is #2: when fitting regularly spaced data with irregularly spaced data, walk through the irregular stuff and find the corresponding regular stuff: that can be addressed immediately by indexing without requiring a costly search.

    This is macro optimization. There comes a point of time when you actually need to optimize at the small level. Don't go there until your profiler tells you.

    And here is the number one rule for optimizing C code: don't use pointers if you can avoid them.

    There is a clever trick to implement twodimensional arrays as pointer arrays pointing to the actual rows of the array. This saves you a multiplication for pointer arithmetic.

    Making use of this clever trick with modern processors and compilers will cause your performance to drop by about a factor of 5. I am not kidding you. The compiler's aliasing and parallism detection passes are made useless by this technique, strength reduction fails, the out of cache line accesses cause thrashing in memory accesses, and the additionally necessary memory accesses are much slower than address calculation which happens at full processor speed.

    Use C99's variable dimensioned arrays instead: those are not half as confusing to the compiler, and much more efficient, anyway. And, sad to say: think of using numeric subroutines in Fortran when having to deal with multidimensional arrays. C99 has not been around for so long, and almost no code making use of its features exists.

  335. Mod parent up by dpbsmith · · Score: 1

    VERY interesting point. I have three mod points and I'd use one of them here if I hadn't contributed to the discussion.

  336. C wouldn't cut it by Anonymous Coward · · Score: 0
    Not only that, but the vast majority of code written today is UI-centric or I/O bound. If you want real optimization, design a harddrive/controller combo that gets you 1 GBps off the physical platter (and at a price that consumers can afford)


    This job calls for VHDL.
  337. Re:(!done) Pedantic Correction and comments by antispam_ben · · Score: 1

    Since, in C, a false value is a value that is non-zero, comparing to some constant "true" wouldn't work pefectly all the time.

    No, you (obviously) meant to say "a true value is a value that is non-zero..."

    At least it's in English and a well-understood mistake, rather than being actual code that would compile and then fail at some later, inappropriate time...

    What you're saying is (since C iplays loose and fast with integer and boolean values - IIRC, in the original K&R they're the same type, perhaps they still are in ANSI) there can be more than one value of 'true', and so the comparison of value==true can be dangerous: it will fail when they are both non-zero and not equal to each other.

    This is one of several 'gotchas' that new C programmers (eventually) learn to avoid, often the hard way. At first it looks so neat to be able to #define FALSE and TRUE and this and that, then play fast and loose with boolean expressions that "ought to work" because they read just like English sentences...

    Strong typechecking (as in Pascal) fixes the problem, but makes older C code not work. The real problem this generates is that C programmers will tell you "We LIKE mixing integers with booleans in this way, it makes our code more terse and easier to read." And in a real sense that's correct. How do you argue with tradition...

    --
    Tag lost or not installed.
  338. Not performance...but helpful by Erik_Kahl · · Score: 1


    I prefer to use:

    if (NULL == var)

    and reduce the chance you'll wind up with a typo that totally changes the meaning of the statement.

    Say you happen to forget a '=' character in there. Easy to do if you're typing quickly and a bit tired. Sometimes the little statements get overlooked and you move onto the meaty logic.

    if (NULL = var)

    Would generate an error your compiler should tell you about...

    if (var = NULL)

    Will generate an error your users will tell you about... Or, maybe it will just result in silent data loss or a happy little memory leak. Who knows, but it won't be one of the good features.

    The same holds true for any use of a comparison operator. Its better to have the variable component in a place where it can't be assigned to by accident.

  339. Re:Clear Code (FP pedant) by 3.1415926535 · · Score: 1

    a) Writing 0f or 0 doesn't matter if var is a float, because the compiler will infer the right type for 0.

    b) Did you even read what I wrote? I said it prints the wrong thing if the number is exactly 0.0f. Everything else worked fine.

  340. Finally, a story that my signature works well with by smcdow · · Score: 3, Interesting

    I've been using it for a while...

    --
    In the course of every project, it will become necessary to shoot the scientists and begin production.
  341. Never do (x==NULL), do (!(x-NULL)) by eXocomp · · Score: 2, Funny

    "if (!(x-NULL))" is not only foolproof, but much easier to understand!

  342. Rule of code optimization by Anonymous Coward · · Score: 0

    Don't.

    There's an experts-only version of the law, too:

    Don't yet.

    Remember - most programming evil is the result of premature optimization. That's Knuth's version of the law.

  343. Re:Clear Code - Boeing by flargleblarg · · Score: 2, Funny

    So how many dumps does it take to fill up the crapper tank?

    Man, due to budget cuts, I'd hate to be the one guy whose job that is.

    "Hang in there, you only have 17 craps to go. Here, have another burrito."

  344. (NULL == ptr) is the more correct choice by Anonymous Coward · · Score: 0

    beacuse (ptr == NULL) is too easy to accidently mis the extra = and make an assignment. Do yourself a favor, and always put the constant to the left.

  345. Avery Lee says... by Grendel+Drago · · Score: 1

    Avery Lee of VirtualDub fame says (scroll down to the 3/17/2004 news) that MSVC compilers suck horribly at optimizing MMX or SSE code. Check out his examples. I wish I knew assembler so I really could understand how horrible they are.

    --grendel drago

    --
    Laws do not persuade just because they threaten. --Seneca
  346. Re:Clear Code - Boeing by Impy+the+Impiuos+Imp · · Score: 1

    > So how many dumps does it take to fill up the crapper tank?

    Just wait until there's a snowstorm at Detroit Metro again, and Northwest planes are trapped for 8 hours or more with no effort to go get the people out with even a 1950's style push stairs and you'll learn how much poop will overflow a toilet.

    One hopes the pilot can override the lockout, at least on the ground, or they'll start shitting in the galley instead. I hope these engineers thought of that. I'll bet not.

    --
    (-1: Post disagrees with my already-settled worldview) is not a valid mod option.
  347. I've yet to decide between (ptr==NULL) and (!ptr) by eXocomp · · Score: 1

    One the one hand, I like "if (!ptr)" because it's terse yet logically intuitive; "if (!ptr)" means "if the pointer does NOT point to anything". One the other hand, I like "if (ptr==NULL)" because then I can do a search for "NULL" and find all instances of pointers being tested for pointiness. As a result, I use a mixture of the two in my code. D'oh!

  348. Optimization by AaronW · · Score: 3, Insightful

    In terms of optimizing, generally compilers do a pretty good job, however there are several areas that no compiler I know of can help.

    1. Choose the right algorithm. For example, in an embedded project I worked on an engineer used a linked list to store thousands of fields that must be added and deleted. While adding is fast, it didn't scale for deleting. Changed it to a hash table and it sped it up significantly.

    2. Know your data and how it is used. Knowing how to organize your data and access it can make a huge difference. As a previous poster pointed out, sequential memory accesses are much faster than random accesses. I had to do some 90 degree image rotation code. The simple solution just used a couple for loops when copying the pixels from one buffer to another. In another, I took into account the processor cache and how memory is accessed and broke it down into tiles. The first algorithm, while simple and elegant ran at 30 frames per second. The other ran at over 200 frames per second. Looking at the code the first algorithm should be faster since the code is simpler. Both algorithms operate in O(N) time, where N=width * height.

    Further optimization attempts to hint to the CPU cache about memory made no difference (Athlon XP 1700+). The only possible way I see to speed it up further would be to write it in hand-coded assembler.

    3. Reduce the number of system calls if possible. Some operating systems can be very painful when calling the kernel. Group reads and writes together so fewer calls are made.

    4. Profile your code to find bottlenecks.

    5. Try and keep a tradeoff between memory usage and performance. A smaller tightly packed data set will execute faster with CPU caches and will reduce page faults when loading and starting up.

    6. Try debugging your code at the assembler level, stepping through it. It will help you better understand your compiler.

    7. Don't bother trying to optimize things like getting every ounce of performance when the next function you call will be very slow. I.e. in one section of MS DOS's source code which was hand-coded assembly language it was calculating the cluster or sector of the disk to access. First the code checked if it was running on a 16-bit or 32-bit CPU. Next it took the 16-bit or 32-bit path for multiplication, then it read from the disk. Why the hell write all this code to check the CPU if it's 16 or 32 bit for the multiply when the frigging disk is going to be slow. They should have just stuck with the 16-bit multiply rather than be clever.

    In general applications with GCC, I rarely see much difference between -O2 or -O3. For that matter, I often don't see a noticable difference between -O0 and -O3 for a lot of code.

    I only see improvements in some very CPU intensive multimedia code. I also saw a significant improvement in some multimedia code when I told the compiler to generate code for an Ultrasparc rather than the default, but that's because the pre-ultrasparc code didn't use a multiply instruction.

    -Aaron

    --
    This post is encrypted twice with ROT-13. Documenting or attempting to crack this encryption is illegal.
  349. Don't care by wandazulu · · Score: 1

    I wrote a chart control in C++ where I used bitshifting instead of multiply/divide and that is the only time (so far) where I was trying to squeeze maximum performance out of my app.

    For the most part, unless you're writing anything with hard deadlines (RTOS', graphical stuff where visual matters, etc.) the time to look at the assembly is time wasted; better to get your algorithms right than to cut 10 instructions to two. Besides, most of the time, especially if you're doing "business"-related work, you're going to probably be bound by the disk or the network or other factors that makes the point moot.

    So while good assembly is important, I'll trust the compiler does a good enough job for my purposes. However, that's not to say you can't help it along by passing by reference, using the STL properly, etc. Thus I try to strike a balance between readable/maintainable code, and performance. However, given that most of the things I write are business apps, maintenability will always always win out.

  350. Actually... by xRelisH · · Score: 1

    this is where C is different from most languages. C is more machine-like. The ! operator simply returns true if the variable being referenced is 0, and in terms of instructions, I believe this is actually a faster instruction, since most ALU's have an "is zero" line coming out of them.

    A pointer is simply a number, in fact, really every variable in C is actually a number, including arrays that are really just pointers themselves that point to a continuous block of numbers.

    Once beginners understand how generalC is, the rest is very easy.

    1. Re:Actually... by Anonymous Coward · · Score: 0

      A pointer is simply a number, in fact, really every variable in C is actually a number, including arrays that are really just pointers themselves that point to a continuous block of numbers.

      False and false.
      a) Pointers are very different from numbers. If you want to, you can attempt to convert them to numbers, but the result isn't necessarily meaningful. For instance, a pointer might be larger than any integer type on some systems.Beyond the surface they are of course represented as some sort of register-storable values, but you shouldn't think in these terms if you want to code portably.
      b) Arrays aren't pointers to themselves. Arrays are arrays, but they indeed "decay" to pointers to their first elements when used in most contexts. The difference is important one to understand how arrays of arrays work.

      But if you'd like a language where things are indeed as simple as you describe, try B :)

  351. Do not prematurely optimize by dumbnose · · Score: 3, Insightful
    Writing less clear code because you believe it is more efficient is the worst thing you can do for your code. It will only cause bugs in the short-term and create less manageable code in the longer-term.

    Do not perform minor optimizations without first: a) Determining there is a performance problem b) Profiling your code to determine what areas should be optimized.

    This does not mean that you should choose naive algortithms for the problem at hand. Choosing the proper algorithm for the problem at hand is always important.

    Hand-optimized code should be reserved for those times when you have profiled your code with reasonable inputs and have shown that the lack of clarity is compensated for by the increased performance.

    The example you gave is a perfect example of a hand optimization that is completely worthless with today's compilers.

  352. Re:Clear Code (FP pedant) by Impy+the+Impiuos+Imp · · Score: 1

    I gave up doing atomic-level optimizations (loop and algorithm tightening is still OK) the day a buddy saw a compiler, when multiplying by 7, actually did a left shift of 3 followed by a subtraction, which were ALU rather than multiplication operations, and hence much faster.

    --
    (-1: Post disagrees with my already-settled worldview) is not a valid mod option.
  353. Re:Clear Code [NOT] by ArghBlarg · · Score: 1

    I agree, as I have been recently poring through the code for PINE (the email program)... man, the code is very good about checking its pointers and function return codes, but they do it in the most obscure way, using the short-circuit evaluation features of the C language to its max -- as well as implicitly assuming that NULL == 0 == FALSE, which is bad in my opinion as the C standard never guarantees that NULL is actually 0 and FALSE is not a built-in data type.

    I always find it harder to grok

    if( !ptr || !func() )
    return(0);

    than

    if( (ptr != NULL) )
    {
    if( func() == 0 )
    return (0);
    } .. while the code is correct, it's MUCH harder to parse.

    Many actual expressions in pine/send.c, for example, have as much as 6 terms in a single if statement which do a combination of NULL pointer checks, function calls, return codes and error returns.

    --
    ERROR 144 - REBOOT ?
  354. Depends on what you are doing by Anonymous Coward · · Score: 0

    For small scale code snippets (assigning a constant to a variable inside of a loop) the compiler knows to do that one time (outside of the loop) rather than the number of times the loop runs (you are assigning the variable the same constant over and over without doing anything otherwise useful). For larger scale operations where algorithms come into play, coding the algorithm wins (much bigger fish than mere optimization). Example: it's much faster to sort an array of data and do a binary search on it, than to leave it unsorted and do a brute force search on it (if you need to search the data more than one or two times). The search time (average hit time) for the unsorted search is 1/2 of the data. For a binary search, the seek time is ceiling(log(base 2)(data set size)). A million (unsorted records) takes on average 500,000 searches to find what you are looking for. If it's sorted, a binary search takes ceiling(log base 2(1000000)) or 20 searches. Another example of a divide-and-conquer algorithm is the finding of a very large exponent. Say you want to find the answer to 123456789.123456789 raised to the exponent 123456789.123456789...
    first you would split the exponent into a decimal/non-decimal number and use the rule a^(x+y) = a^x * a^y
    then you would use the function a^b = e^(b * ln(a))
    and e^x = 1 + x + (x^2/2!) + (x^3/3!) + (x^4/4!) .....
    and ln(1+x) = x - (x^2/2) + (x^3/3) - (x^4/4) + (x^5/5) ..... ... and solve for the decimal part of the exponent, that is the
    123456789.123456789^0.1234565789 part of the problem.
    The simplton (and silly) way of solving the whole number part of the exponent would be
    to run a loop 123456789 times. But this would take a CRAY
    several hours to crank out. Instead, the better way would be
    to count the exponent in a better function base=base * base
    where the first iteration is base=base *base
    resulting in base ^2
    the second time base=base*base
    results in base ^4 (not base^3)
    note that with a starting value of base^20, base =base * base
    results in base^40
    there is more overhead in counting how much 'exponent' you have accumulated, and how much you have left, but the speed is wildly faster log(base 2) of exponent. You also need to reset "base" when the next iteration will result in an exponent larger than what you want. If your exponent is 2300 and the starting value of base is 2048, the next iteration would be 4096 (which is way past 2300) so you would have to store away the result, and start again. ...If the exponent is 2300 the whole process winds up looking like you are taking the product of base^2048 * base^128 * base^64 * base^32 * base^16 * base^8 * base^4. ...2048+128+64+32+16+8+4=2300 and you will have to keep track (count) how much you have accumulated. It looks like a lot more work and overhead, but it's wildly faster.
    Oh, and by the way 123456789.123456789^123456789.123456789=
    1.902372 233125202254900477527601440455865041458687 62E+998952458
    and it took the comptuer
    real 0m0.094s
    user 0m0.062s
    sys 0m0.005s
    to finish it. That's an algorithm a compiler can't do (the result was actually done using an interpreted language, not a compiled one although if it was done with a compiled language it *would* be faster, and if /.ers really want to see how long 500 significant digits takes, just double-dog-dare me with a post). ...oh nevermind....
    1.902372233125202254900477527601440 455865041584523 00932547800628012504668725985753569183588310325552 14891761772476982389287105899631335303898726939229 31310705257116814311279734672618273312947900668347 68090730923077415613982473794558850107588669012433 89234455684479444134741340809934899813201850775621 76899291838534784375714952525802050621884047640666 05875927322449991298143

  355. Amen by Bozdune · · Score: 2, Informative

    Let's not forget how long it took them, either. I worked with some of the Shuttle programmers. I shared an office with one pudgy little 40-something bald guy who wrote about three lines of code per month. He had a big loose-leaf notebook full of all his test cases and his test jigs and his interfaces and his error checks. He worked for another guy who used to hold 1/2 day meetings every two days. In the time I shared a cubicle with him, probably 3 months, he had accomplished a whole lot of nothing.

    As far as how together and structured the Shuttle group was, I remember the day there was a head crash on the 3330 drive that held all their source code. It was like turning over an ant nest, programmers scurrying around the halls screaming, etc. Don't believe everything those people write about how well they were organized and how wonderful everything was.

  356. Get it right! by Anonymous Coward · · Score: 0

    After more then 30th years of coding I have learned that if you want to "get it right" you must always get an assembly listing of the compiled code. This is the only way to verify that what was generated by the compiler is what you want the mechine to execute. Not only does this result in faster and/or smaller code, but also in zero defect code.

  357. C++ and hand arranging of code. by jholzer · · Score: 1

    C++ still requires some undestanding of hand optimizations specific to the language.

    I don't think compilers optimize this construct.

    for(;;)
    {
    MatrixClass C(3,3); //do something with class.
    }

    The C++ compiler will call the constructor/destructor every loop when it probably isn't needed. C++ and the "hidden" memory allocation, constructor, destructor calls can be a problem without arranging the code properly by hand.

  358. Yep by Craig+Ringer · · Score: 1

    That's the way. Write code that doesn't need comments to be understood, then comment the damn thing anyway ;-)

    There's very little more helpful than comments scattered through the code explaining the "bigger picture" - /why/ this routine does this this way, etc. Those are usually things you can't impart through the code its self anywhere near as easily.

  359. Changes in CPUs can trump compiler optimizations by bzipitidoo · · Score: 1

    Sometimes it's not the compiler doing the optimization. On an 8086, division was slow. /2 was a lot slower than >>1. It was possible to write a division function with shifts and subtracts that was faster than the DIV instruction. But now, the division function within Pentiums is optimized so that /2 is just as fast as >>1.

    --
    Intellectual Property is a monopolistic, selfish, and defective concept. It is "tyranny over the mind of man"
  360. Re:Parent is a sicko furry by Anonymous Coward · · Score: 0

    bestiality = cruelty to animals (mental, if not necessarily physical) = not the kind of thing I want happening.

    feel free to fuck any consenting adult you want, however you want. don't molest animals.

  361. I noticed that too by toadlife · · Score: 1

    'if (!ptr)' instead of 'if (ptr==NULL)'.

    I only know a few high level programming languages (PHP, VBScript, and a few other misc languages), but it was my belief that with most programming languages, something can't be equal to nothing.

    I have no idea what language the above code snippet is supposed to be, but I read the first code snippet as "if ptr is false". The second example jsut looks plain illogical to me.

    What programming language supports that second code snippet? C/C++?

    Isn't it good practice to keep "NULL", "false", and "0" seperate, since they are distictly different concepts?

    --
    I don't always use unix-like operating systems; but when I do, I prefer FreeBSD.
    1. Re:I noticed that too by JaxWeb · · Score: 1

      The code is in C (and so C++ and related languages).

      C doesn't have "NULL" as such, but NULL is generally defined to have the value 0. Since no memory location has the value of 0, it makes sense that if you have a variable which stores a memory location (a pointer), you give it the value 0 - so it is pointing to the memory location 0. When dealing with pointers, however, we generally use "NULL", not "0", despite them having the same values.

      So,
      if ( ptr == NULL )

      is basically saying "If the number stored in ptr is 0".

      PHP treats NULL very differently, which is probably where your confusion comes from.

      NULL is defined to be 0. Also, false is defined to be 0 (and true is defined to be 1, normally, but really it is "Not 0"). Hence they are really all the same thing, but just used in different situations - they are actually interchangeable.

      Hope that helps.

      --
      - Jax
    2. Re:I noticed that too by Renegrade · · Score: 1

      Actaully, the zero/NULL thing is just an abstraction in C.

      When you say something like "char *ptr; if(ptr==NULL) ..." or such, the compiler notices that you're comparing a pointer to the value zero, and will then generate machine code that checks it against the machine/OS specific invalid address value, rather than an actual comparison to zero.

      Note - This physical null value happens to BE zero on most machines/OSes, but on some others it's weird stuff like $3F:FFFFFFFF.

    3. Re:I noticed that too by Anonymous Coward · · Score: 0

      Oh I never knew that. Thanks

      - Jax Web

  362. Readibility by Kell_pt · · Score: 2, Informative

    I must say I don't agree with the author's remarks on readability. I use
    if ( !ptr )
    throughout my code for ages and always felt that to be far more readable, and so do my colleagues. It's also faster to type.
    It reads "if no pointer" which is far understandable than "if pointer is null". Because pointers aren't really null, they are zero.

    Mostly, it's just a matter of style. Imho, if you have trouble reading either of these though, you're using the wrong language - for your own safety stay away from Perl aswell. ;)

    --
    "I don't mind God, it's his fan club I can't stand!" E8
    1. Re:Readibility by Jeremi · · Score: 1
      Because pointers aren't really null, they are zero.


      If pointers can't be null, what does the word "null" mean in a programming context? Is there something other than pointers that can be null? Or are you saying that the word "null" has no application at all?

      --


      I don't care if it's 90,000 hectares. That lake was not my doing.
  363. Hey hey hey by peccary · · Score: 1

    I shared an office with one pudgy little 40-something bald guy

    Who you calling pudgy?

    Slashdot is full of pudgy little guys who are working hard on becoming 40-something and bald.

    Though I'd hope to do something about the pudgy bit by the time I turn 40, my track record ain't so good.

  364. I hold the opposite is true by Ars-Fartsica · · Score: 1

    I have found that over the years, very few problems require complex algorithms that have not already been coded. Knowing a library (STL, etc) very well and the language that implements it has almost always trumped knowing how to implement mergesort. If you think differently, go code up quicksort and then look at the std implementation....whoops, you are not as smart as you thought...the std library uses all sorts of language tweaks to blow the doors off of yours.

  365. /. posters by Saville · · Score: 4, Insightful

    "I ask the Slashdot crowd, what they believe the compiler can be trusted to optimize and what must be hand optimized? Give examples of code optimizations that you think the compiler can/can't be trusted to do."

    Somehow 99% of the readers took this to mean "What is the difference between NULL and the zero bit pattern and do you think it is a good idea to write clear code and do the profile/algorithm change cycle until there is nothing left to optimize or should I write low level optimized code from the start?"

    sigh.. I've only found two comments with code so far after going through hundreds of posts. This is possibly the worst signal to noise ratio I've witnessed on /.

    1. Re:/. posters by Quill_28 · · Score: 1

      You new around here?

    2. Re:/. posters by Fledsbo · · Score: 1

      I'll give you one (might be posted already, but I cba to go through every post):

      Inside your sorting function, do :

      if (a = b) {
      if (a b) {
      return -1;
      }
      return 0;
      }
      return 1;

      instead of

      if (a b) {
      return -1;
      } else if (b a) {
      return 1;
      } else {
      return 0;
      }

      At least with my gcc with -O3, the first one is a single cmp, while the last one is two.

    3. Re:/. posters by Anonymous Coward · · Score: 0

      Don't complain about the noise ratio when you are part of the noise.

      I'm part of the noise as well, but I'm not complaining :)

    4. Re:/. posters by cimetmc · · Score: 1

      That's simply because your first test is wrong and the inner compare is useless because at that pount a is equal to b.
      In any case, even if your code were correct, it would be a good example of futile source code optimization as the exact order in which the comparisions would be done would depend on the type of compiler and the exact compiler version. However for compound comparisions like that, a lot of compilers (and this includes GCC) have a tool to optimize this and this is profile feedback optimization. You first compile the code with -fprofile-generate (for GCC). Then you run the program a couple of time with more or less typical data, and then you recompile the program with the option -fprofile-use. During this second compilation, the compiler will take advantage of the knowledge of which test result is the most likely for each test, and it will rearange the code to reduce the number of jumps or rearange tests so that the most conclusive tests are done first.

      As for the person who claims he finds no useful answers here, he just has to open his eyes. Especially among the first answers there were a number of pretty good suggestions. However let me iterate some of the ideas in my own words:

      * whether it is about using !x or x==NULL or what type of loop to use or how to nest tests, that's just a matter of coding style. Changing between coding styles is just a matter of trivial code transformation and any optimizing compiler can do trasnformations like that. As such, such coding style decisions should not have a significant impact on code performance

      * based on the previous point, you should always write your code for human readability. If you obfuscate your code just for performance reasons but you neglect readability, you are creating yourself a maintenance nightmare and you will be the big looser in the end

      * before even thinking about optimizing your code, first optimize your algorithms. For instance, if your program does some kind of searching in a huge list, instead of using a linear search, use a binary search, or better even a hash table to potentially get much greater speed gains than by just rearanging your code

      * investigate the options the compiler gives you to optimize your code withough modifying your source code. There is generally mucgh more than just the -Ox options. For instance, selecting the appropriate target processor is important. For floating point code, if you don't need strict IEEE conformance, optionms like -ffast-math can give you huge performance gain. If your code oonly runs on SSE enabled processors, you can play around with the SSE floating point options ...

      * if you really need to microoptimize your code, always use a profiler. First try to find your hotspots. There is no need to optimitze code that is rarely executed. Then check if your changes do really make a performance difference. Don't judge the code just on the source code. With modern processors, the shortest code or the most simply looking isn't always the automatically the best.

      Marcel

    5. Re:/. posters by m50d · · Score: 1

      I'll restate what I said earlier, but perhaps more in context. Unless you're one of about ten people, the compiler probably knows the language better than you do. So don't bother trying to outguess it. If you really need it super-hand-optimised, inline assembly. But don't try to write optimized C, other than at the algorithm level. Every possible C implementation of a given algorithm is likely to compile to more or less the same.

      --
      I am trolling
    6. Re:/. posters by djplurvert · · Score: 1

      In general I agree, however, this isn't always true. Manual loop unrolling can offer significant improvement over what the compiler can do for you in certain circumstances. The problem is that it's probably not obvious what is the precise amount of unrolling that will work well.

      Now, that said, I'm not talking about the kind of code that most people write, I'm talking about highly cpu intensive and very repetitive numeric code. I can't remember doing that sort of speed optimization in any commercial application.

      I have done things for size optimization for embedded systems. However, they typically have simple architectures that are faily easily understood.

    7. Re:/. posters by Fledsbo · · Score: 1

      I'll try once more with escaped <'s // fast
      if (a <= b) {
      if (a < b) {
      return -1;
      }
      return 0;
      }
      return 1; // slow
      if (a < b) {
      return -1;
      } else if (b < a) {
      return 1;
      } else {
      return 0;
      }

      Knowledge of the input data can help you or your compiler put the right jump first, but there is never any need for two compares in there. Organizing the code like this helps the compiler optimize it correctly. I did learn this the hard way, and therefore always organize my compares like this inside sorts.

      Of course this depends on your compiler and version, but there's nothing wrong with having some knowledge of your compiler when you're writing performance crititcal code.

  366. New methods by abbashake007 · · Score: 1

    C is definitely not going to be the language of the future. There are a lot of tools for "checking" or "purifying" C code, but real promise is in radical new approaches based on reusable objects. As far as a systems programming language goes, the Cyclone project at Bell Labs http://www.research.att.com/projects/cyclone/ is one way to get away from C.

  367. Stupid Micro-optimizations by Anonymous Coward · · Score: 1, Insightful
    'if (!ptr)' instead of 'if (ptr==NULL)'. The reason someone might use the former code snippet is because they believe it would result in smaller machine code if the compiler does not do optimizations or is not smart enough to optimize the particular code snippet. IMHO the latter code snippet is clearer than the former, and I would use it in my code if I know for sure that the compiler will optimize it and produce machine code equivalent to the former code snippet.


    The example given is down right stupid!!!
    Who cares if it takes an extra usec to process ptr != NULL. How irrelevant. It won't change the efficiency of the program at all!!

    This is what bugs me about "the C culture".. always concerned about micro efficiency. It is what stopped the C and C++ crowd from ever getting to real questions of over all design and efficiency (which are more often the cause of project failure).

    Projects fail because the data requires moving/transformation, because you do more drawing than necesary, because you use bad algorithms and can't change them because you didn't design for that, because code is messy. None of these things can be solved by a compiler.

    1. Re:Stupid Micro-optimizations by chawly · · Score: 1

      While the is a lot of truth in what you're saying, you really should read the text all the way to end. He does actually say that his example is simple - but it is short. He asks for a broader approach from the reader, I think.

      --
      How many beans make five, anyhow ? ... Charles Walmsley
    2. Re:Stupid Micro-optimizations by codehouzi · · Score: 1

      I don't know. if (!ptr) is an incredibly common idiom in C. So, for seasoned C programmers, 'if (!ptr)' is pretty much just as readable as if (ptr == NULL).

      In fact, when I maintain code, seeing something like if (ptr == NULL), usually makes me a little nervous. Not because if (ptr == NULL) itself is bad, but because it usaully indicates that who ever wrote the code is either new to coding in C, or minimally just doesn't code in C too often. If either of these are true, this usually means the code has an increased number of weird and/or anonying bugs.

  368. You must not have a GBA by tepples · · Score: 1

    what the fuck handheld device has only 384k of RAM?

    This the fuck handheld device has only 384k of RAM.

  369. Simple by ciph3r · · Score: 0

    Well... I think Einstein had it right all along...

    "Things should be made as simple as possible - no simpler."
    - Albert Einstein ... My head hurts.

    --
    -ballpark
  370. HLSL by Saville · · Score: 3, Informative

    As far as I'm concerned compilers are better than 99% of the programmers out there. Just write clear code and let the compiler do it's trick. However there are a couple cases where things aren't automatically optimized that I can think of.

    It's not really a coding trick like an XOR swap, but most compilers don't yet seem to fully unroll parallel loops into good SIMD instructions or multiple threads.

    The only time I've needed to bother to look at assembly output in recent years (other than debugging a release mode program) is when writing HLSL shaders. HLSL is the high level shading languge (C like) for shaders that is part of Direct3D 9. HLSL can be compiled to SM1, SM2, or SM3 assembly.

    With pixel shader 2.0 you've only got 64 instruction slots, and some important instructions like POW (power), NRM (normalize), and LRP (interpolate) take multiple slots. 64 slots is not enough for a modern shader. I curse ATI for setting it bar so low. ;)

    There are two flaws I've found with the Dec 04 HLSL compiler in the DirectX. Sometimes it will not automatically detect a dot product opportunity. I had some colour code to convert to black and white in a shader and wrote it as y = colour.r*0.299 + colour.g*0.587 + colour.b*0.114; as I thought that was the most clear way to write it. Under certain circumstances the compiler didn't want to convert to a single dot instruction so I had to write as y = dot( colour.rgb, half3(.299h, .587h, .0114h)); I'm not sure if that bug still exists in the current compiler release or not.

    Another is often a value in the range of -1 to +1 is passed in as a colour, which means it must be packed into 0-1 range. To get it back you've got to double it and add 1.
    a = p*2+1; gets converted into a single MAD instruction which takes one slot.
    a = (p-0.5)*2; gets converted into an ADD and then a MUL.

    Also conventional wisdom says you've got to write assembly to get maximum performance out of pixel shader 1.1 as it is basically just eight instruction slots. I don't have any snippets to verify this though.

    I think this thread demonstrates that either compilers are mature enough you don't need any code tricks to help them do their job or /. posters just aren't aware of the short commings of compilers (see first sentence of this post) and would rather post obvious advice than not post at all. :)

  371. Nooo! not quicksort!! by rufusdufus · · Score: 1

    Quicksort has a worst case run time of N^2. A largish list can occasionally take *days* to compute, even though the average time is a millisecond.
    Heapsort or mergesort is what should be used in any critical service.

  372. In most cases by Z00L00K · · Score: 3, Informative
    I try to write code that is simple to read and avoid complex statements. This is often easily optimized by the compiler and more important readable for whoever is doing maintenance on the code.

    For the rare performance critical parts it is however worth the effort to try various constructions to get the best performance out of the code. The most problematic issue is to identify the hotspots in the code and figure out which variables that should be declared as 'register' and those that shouldn't. Ordering of statements are also important in order to match the various performance improvments the CPU can offer. One very good document on this is actually found at AMD.

    One code construct that I am using that I found is very useful is to place the matching '{' and '}' in the same column in the code. This eases the effort trying to find where a block begins.

    Example:

    if (a == b)
    {
    printf("Hello!\n");
    }
    In my opinion this produces code that has an improved readability compared to the constructs placing the '{' on the same line as the if-statement where it is much easier to miss.
    --
    If builders built buildings the way programmers wrote programs, then the first woodpecker would destroy civilization.
  373. Answer by thorax · · Score: 1

    I don't use compilers anymore.. I did in college,
    but being a web programmer I use only interpreters.. But I never stop thinking about optimizing my code, I don't trust the interpreter to make things faster..

    What I do in PHP, for instance is

    $a = &$b;

    Which is a pointer assignment..

    But for some strange reason, everyone says
    this is slower than

    $a = $b;

    Which really doesn't make sense..

    --
    He knows enough to ruin the world and his own. Does he know enough to change himself and the world as well?
    1. Re:Answer by t_allardyce · · Score: 1

      Actually PHP automatically references variables so when you do $a = $b or $some_array = $a_very_big_array, PHP will automatically make it a reference/pointer and keep track of everything for you, memory management is teh r0x0r. I find its better to write very readable code and then look at which bits are causing problems - tight loops etc, and then optimise those. And of course if you really want to get some extra speed in PHP you can always write your own module for a particularly slow task, nowadays tho, its often cheaper for a business to upgrade their servers and use bad code rather than pay programmers to optimise.

      --
      This comment does not represent the views or opinions of the user.
  374. How useful... by Flaming+Death · · Score: 1

    A topic that guarantees to get every programmer to post to slashpot.. what batter way to stir a programmer.. tell them compilers can do a better job...

  375. Homework? by wplittle · · Score: 1

    Is this a homework question?

  376. Tiling by ShakaUVM · · Score: 1

    Look into Compiler Tiling. It's all about reordering loops into ways that are more cache friendly.

    Compiler writers are smart people.

    1. Re:Tiling by Hast · · Score: 1

      Not only that but compilers are a lot better at some optimisations than humans. Eg Software pipelining is something that you can do as a human but try to do it for a general case with super scalar computers and it soon becomes prohibatively hard.

  377. Does anyone think this even matters? by Bruce+Perens · · Score: 2, Insightful
    People have 4 GHz CPUs these days and somebody is worried about the difference between !p and p==NULL? If any compiler actually assembles code with a speed difference for those examples these days, it might well be that the speed difference is one billionth of a second. And even if that code is in a tight loop, it's entirely irrelevant given that the memory bandwidth is probably the governing factor rather than how fast the CPU can do integer vs. 0 tests.

    Hey, my phone has a 400 MHz processor.

    Bruce

    1. Re:Does anyone think this even matters? by R1ch4rd · · Score: 2, Informative

      That's 99% true, but then there are those 1% applications were it does matter. I'm writing real-time computer vision applications and 1/2 a millisecond still counts. And you have a piece of code running 1000's of times which MUST be as fast as possible. So it's a valid question after all. Richard

    2. Re:Does anyone think this even matters? by Bruce+Perens · · Score: 1
      Yes, I did some image processing at Pixar. My point was that you can't read or write the memory as fast as you can do an integer compare. So, below the point at which memory bandwidth becomes the governing factor, the speed of your algorithm makes no difference.

      Bruce

    3. Re:Does anyone think this even matters? by Cramer · · Score: 1

      This is a BS falacy. It's the reason current OSes and applications are 100,000 times larger and more complex than what came before them. If no one cares about doing anything efficiently, then nothing will be done efficiently. Just because your thumb cannot push the button on your stopwatch fast enough to measure the difference between 5 and 100 machine level operations is meaningless.

      We need faster processors not to do more things, or do the same things faster, but to simply maintain the same levels of productivity because our OSes and applications are ever increasingly bloated and inefficient. We need faster processors because the code is less efficient; and we don't write efficient code because we have faster processors. This is the loop of BS we've lived with for years.

      I can remember running entire "office" packages from one single sided, double density, 5.25" floppy (that's 180K, btw) -- which included the entire OS for the applications (OS-9/6809.) That was in the days when Windows came on seven (7) high density 3.5" disks (1.44M each) and office was another stack of floppies. Imagine how much more we would have time to do if programers today were like those from 10-20 years ago when every bit and every instruction mattered.

      [And now for my dead horse...]
      For the crown jewels of lame inefficiency, look no further than the slashdot reader's beloved Linux. How does an application find out how many CPUs there are in the box? The kernel knows this milliseconds after boot and carries it around as an int it's entire life. But that simple, efficient, little number is NEVER exported to userspace. Ever. What would (minus any syscall overhead) ultimately be one mov instruction to give something the kernel has always known to userland turns into literally THOUSANDS of instructions both in userland and the kernel to generate and process all the (arch dependant) human formated ASCII text of /proc/cpuinfo.

      The point extends to just about everything in /proc... look at all the waste of coverting things to ASCII for humans to read (which, btw, is usually not read by humans), converting them back to binary, to then convert them back to ASCII to show to a human.

    4. Re:Does anyone think this even matters? by Bruce+Perens · · Score: 1
      We need faster processors not to do more things, or do the same things faster, but to simply maintain the same levels of productivity because our OSes and applications are ever increasingly bloated and inefficient. We need faster processors because the code is less efficient; and we don't write efficient code because we have faster processors. This is the loop of BS we've lived with for years.

      I wrote a program in 1996 or so called busybox, which has been adopted by the embedded Linux industry. It, the Linux kernel, and the Almquist shell make a pretty comfortable command-line environment. At the time I wrote it, the whole environment would boot from a 1.44 MB floppy. It's still very small, even with the 2.6 kernel and the fact that 100 commands have been added to busybox since then, and runs in a lot of embedded devices. If you want tiny environments, they are still available, and some of us have not forgotten how to write them.

      I wrote 29000 bit-slice microcode in the 80's at Pixar, and could sit all day working on getting the last clock tick possible out of a single tight loop. That CPU ran the predecessor of MMX at 40 MHz. Today, if I did that it might not even matter, because once you get over a certain speed, you can't read and write RAM as fast as the CPU can demand it.

      It's not really that we need more powerful machines to do the same thing. It is that we are using every bit of power that is offered to us. For instance, 3D animated film frames used to take 5 minutes to render on a 250 MHz CPU. Today, with a 4000 MHz CPU, they take 5 minutes to render! But the animated characters now have realistic looking hair, which would never have been possible with that VAX.

      It's true that I often write slower code these days, because I write more in Ruby than in C. But you can buy a new computer for what it would cost to have me work on something for three hours. So, it's a good trade.

      Bruce

    5. Re:Does anyone think this even matters? by Bruce+Perens · · Score: 1
      How does an application find out how many CPUs there are in the box?

      I usually read /proc/cpuinfo. And this is another area where speed does not matter. I read it once, in an interpretive program, and it's easier to program that using the ASCII than it would be to parse yet another binary interface. If I want it in a fast integer variable accessable from tight loops on compiled code, I can put it in one after I read it.

      People are worth more than computers.

      Bruce

    6. Re:Does anyone think this even matters? by Anonymous Coward · · Score: 0
      People are worth more than computers.
      BLASPHEMY.

      You're lucky this post is hidden more than 10 comments from the top, else it might be noticed. You would lose your status as an open-source spokesman, and with it your $50000 sugar daddy too!
    7. Re:Does anyone think this even matters? by Nevyn · · Score: 1
      What would (minus any syscall overhead) ultimately be one mov instruction to give something the kernel has always known to userland turns into literally THOUSANDS of instructions

      Of course that mov breaks horribly with HT CPUs, then you might want to know about multicores ... and god forbid you need anything like a numa layout.

      Oh, and I've yet to see an application that needs this kind of information in a tight loop ... and if you do most people would just call sysconf(_SC_NPROCESSORS_CONF) or sysconf(_SC_NPROCESSORS_ONLN) once, and put it in a variable.

      A lot of the "bloat" I see is from people saying "Oh, we can't possibly link to a decent string library that's way too much bloat for what we need" ... and so, of course, everyone reimplements 65% of one badly. Repeat X times for all the other common non-problems.

      --
      ustr: Managed string API with ave. 44% overhead over strdup(), for 0-20B
    8. Re:Does anyone think this even matters? by Anonymous Coward · · Score: 0

      Hey, my main desktop has a 400 MHz processor, you insensitive clod! But still, I agree with you 100%. Getting p out of RAM is going to take many cycles, but there is something even much more important: when do you check whether a pointer is null? After you allocate memory! Now, if you can possibly detect a one clock tick (at most!) difference between two ways of checking the returned pointer after a malloc, now that's something to post on the Slashdot front page!

      In fact, I just opened up my editor and started to write a benchmark, but I decided that I need to go out more often...

    9. Re:Does anyone think this even matters? by Cramer · · Score: 1

      You do know what's in glibc behind the sysconf calls, right? The very processing I'm bitching about. The kernel knows all this information in very efficient, simple, structures. And yet, they are not exported to userland -- and by Linus' decree, never will be. Other systems have no issues with exporting the kernel's CPU information structures -- even in NUMA configurations. (Even SCO exports this shit properly.)

    10. Re:Does anyone think this even matters? by rjshields · · Score: 1

      Hey, my phone has a 400 MHz processor.

      Yeah, it still matters for systems programming - OS kernels, drivers, that sort of thing. You know, the kind of things people use C for. When it comes to application programing - the stuff that's built on top of the system - that's when code readability becomes more important, and people start using higher level languages like C++ and Java. The example is defunct in Java since there are no pointers and you can't evaluate an int as a boolean.

      --
      In this world nothing is certain but death, taxes and flawed car analogies.
  378. Puh-leez. by ExoticMandibles · · Score: 1

    if (!ptr) and if (ptr != NULL) are exactly the same thing. It's like asking "which is cheaper, six eggs or a half-dozen eggs?" Show me the compiler that generates different code for those two snippets.

  379. Re:Code, Compiler and Optimization by Anonymous Coward · · Score: 0
    ...to mind-bending e.g. C++ (I am convinced that not even Bjarne Stroustrup understands this evil language)

    In other words:
    "I'm too stupid and lazy to learn something challenging but rewarding, and I'm prone to talking like an asshat."

  380. Never trust the compiler! by Flu · · Score: 1
    Working with embedded software, I know for a fact that things that intuitively ought to be more effiecent, doesn't nessecarrily be that. The only things that can be trusted is the compiler output - which is valid for that version alone, and might change if I change some other part of the code.

    For example, for one loop, a=i++ became the best thing, but for another one, writing the code such that I could do a=++i was better!

    In another (8-bit) compiler, writing to word was more effiecent than reading from a word, even though the CPU contained the requred instructions for equal effiecency.

    When there's no particular need for speed, I just write for clarity. If I know that a function will be called several times, I sometimes make several attempts to find out what becomes the best code.

    But in the end, leaving C and using the best possible assembler-algorithm might be the only option, since that way, for carfylly crafted code, I've experienced 5-10 times speed improvements, compared to the best possible algorithm in C.

  381. Reminds me of a strange issue in VBScript by TakaIta · · Score: 1
    VBScript has the native functions IsNull() and IsEmpty(), and also the keywords Null and Empty.

    For some unexplained reason VBScript evaluates the expression "" = Empty to True, but IsEmpty("") to False.

    The issue has been discussed here

    1. Re:Reminds me of a strange issue in VBScript by Anonymous Coward · · Score: 0
      VBScript has the native functions IsNull() and IsEmpty(), and also the keywords Null and Empty.

      For some unexplained reason VBScript evaluates the expression "" = Empty to True, but IsEmpty("") to False.

      Well, for one thing, "Empty" and "IsEmpty" are intended to be used with variables, not constant expressions. Surely you already know whether an empty string is empty?

      Just because a certain usage is legal doesn't make it meaningful.

    2. Re:Reminds me of a strange issue in VBScript by TakaIta · · Score: 1
      First of all it is a matter of principle. VBS just is not consequent. Of course it is silly to do an IsEmpty on a constant, but the code is just to show the inconsequence. Using a variable in stead of a constant gives the same results.

      And it also has real-program consequences. If a variable taken from a database is compared Request.Form("somename"), and something should happen if they are equal, then strange things can happen with one being a zero-length-string and the other missing.

  382. I would have won that bet by Paul+Crowley · · Score: 1

    when I worked for a computer graphics company. What we sold was a routine for very fast voxel rendering. Our bottom line depended on the speed of the voxel rendering inner loop, and we beat the shit out of it. I wrote the reasonably clear, comprehensible version; then I spent a day with an optimization expert called Roger (Sayle, of Rasmol fame), who would send me off to get printouts of the assembly we generated and re-wire the code based on that, as well as on benchmarks of course. The code ran about 50% faster - a vitally important saving - but it took me another half a day to explain to the rest of the team how the code worked after it had been thoroughly Rogered.

    1. Re:I would have won that bet by severoon · · Score: 1

      See, that's one of those very special circumstances where optimization is the only way to go. In graphics, that's the case more often than in any other branch of code development.

      --
      but have you considered the following argument: shut up.
  383. the question is... by dna_(c)(tm)(r) · · Score: 1
  384. Actually by baadfood · · Score: 1

    I favor the "if(!bob)" style because I find it more readable.

  385. If that's true.... by TheLink · · Score: 2, Interesting

    If it's 99% true, then perhaps more than 80% of programmers shouldn't be writing in C. (Judging from the posts on this discussion I think I'm right ;) ).

    Because IMO nowadays writing in C is usually a premature optimization.

    With all the GHz CPUs, higher level languages are often more than fast enough. It's usually the design and algorithms that you have to get right.

    The advantage of writing in a higher level language first is you write far fewer lines of code - esp if the Customers keep changing their minds every month.

    Optimizing at low levels only gives you linear improvements in speed. Doesn't help you if the system slows exponentially.

    What I mean by linear is:

    Say you use the same algorithm.
    #1: fast low level language, optimized.
    #2: in a fast low level language.
    #3: high level language.

    If #3 is 4 times slower than #1 in most cases it'll always be 4 times slower. Same if #2 is 10% times slower than #1.

    Whereas a high level optimization can gain you lots more.

    On a fair size complex system it's probably best to write stuff/modules in a high level language first and then replace them with C or hand assembly later if necessary.

    Maybe it is wasteful. But at least you can say to the people doing it - the informal spec is: "it's got to work exactly like what you are replacing - only faster". After all that module is already working :).

    Call the stuff in the high level language your pseudocode. The equivalent of the plastic/clay model or prototype.

    --
    1. Re:If that's true.... by Bruce+Perens · · Score: 1
      So, I was teaching a class yesterday at a company that makes software. And at one point while answering a question, I blurted out "but then Java's a horrible language". And a few people seemed to be very surprised that I said that. At which point I added "but C and C++ are worse".

      Bruce

    2. Re:If that's true.... by TheLink · · Score: 1

      But Java doesn't seem like a high level language at all. It's like C++ in a padded cell (white straightjacket and all).

      You seem to have to write about the same amount of code. Worse there are all these ratherLongNames.

      Perhaps writing in Java gives Java programmers a sense of achievement.

      A bit like the sense of achievement of waking up early in the morning, walking a mile or two, milking a cow, just for a glass or two of milk for breakfast.

      Rather than just getting it from a milk carton in the fridge (conveniently left there by others who knew you'd want it). And then getting on with the real job.

      Yeah, I've gone soft since my 6502 days. But I'd like to think times have changed ;).

      I wonder if Parrot would help make stuff like Python and Perl run faster. That'll be nice.

      --
    3. Re:If that's true.... by Bruce+Perens · · Score: 1

      I like writing CodeThatYouCanReadLikeANewspaper. That SometimesRequiresLongNames :-)

    4. Re:If that's true.... by TheLink · · Score: 1

      NxG8nRdsSMS :)

      --
    5. Re:If that's true.... by Twylite · · Score: 1

      That raises an interesting thought. Has anyone tried to combine source code with a Wiki?

      --
      i-name =twylite [http://public.xdi.org/=twylite], see idcommons.net
  386. IMO writing in C is premature optimization by TheLink · · Score: 1

    For most cases anyway.

    There are so many disadvantages, and you only get linear improvements in speed.

    Write in a higher level language if you can.

    If some guru optimizes the interpreter or compiler you get a linear improvement in speed.

    Same if hardware gets faster or improves (e.g. 2nd level cache now big enough to fit your entire program).

    If one part is not fast enough, then rewrite that part in C or machine code.

    Call the high level language your pseudocode for C if you want.

    --
  387. No by Peaker · · Score: 1
    Comments should be used LIBERALLY, albeit intelligently as well. If you do something that isn't intuitively obvious to even the most casual observer, just take 30 seconds to write a fucking COMMENT explaining why you did what you did.

    I do not understand what you mean by the "most casual observer"... Typically, casual observers of code are coders, so most code can be written to be obvious to them. That means that comments should be used in the rare cases where it is not possible or very difficult.

    Believe it or not, eschewing comments because "oh, well, if you want to understand it just read the code" just pisses those of us off who have to come along and clean up your miserable excuse for a codebase... and it sure as hell doesn't prove how studly a programmer you are.

    No, programmers should avoid comments for clearer code not because it takes 20 seconds to write them, but because it takes a lot more time to update commented/redundant code and it usually leads to inconsistent and incorrect documentation as the code evolves.

    Comments are a form of redundancy to the code as well as testing, static typing, etc. Redundancy has its advantages but it is mostly disadvantageous as it makes changes difficult and in the case it is not automatically checked for consistency (documentation) it usually leads to the lack thereof.

    That doesn't mean half your codebase should be comments, but it does mean that you should at least make a passing nod to demystifying your own attempts at cleverness. I have lots of better things to do than to spend all fucking day picking apart your rabbit's nest of code before I can make a change, add a feature or fix a bug.

    That's why code should not be clever, it should be simple and as obvious as possible.

    People that honestly believe that "if it's well written it doesn't NEED comments" should be strangled with their mousecord and hung in their cubicles as a warning to the rest.

    A lot of code can be written as to not require comments for proper understanding. The best documentation of what the code does is the code itself:

    Its always up-to-date

    Its always completely consistent with the behavior of the program

    Its not ambiguous

    1. Re:No by jesup · · Score: 1
      No, programmers should avoid comments for clearer code not because it takes 20 seconds to write them, but because it takes a lot more time to update commented/redundant code and it usually leads to inconsistent and incorrect documentation as the code evolves.

      Comments are a form of redundancy to the code as well as testing, static typing, etc. Redundancy has its advantages but it is mostly disadvantageous as it makes changes difficult and in the case it is not automatically checked for consistency (documentation) it usually leads to the lack thereof.

      Yes, comments are a form of redundancy, but this is generally a good thing. Yes, updating comments sometimes adds to the time to change the code - but that is not a bad thing. It can be a good thing if it forces you to think about how the change interacts with the code around it.

      A lot of code can be written as to not require comments for proper understanding. The best documentation of what the code does is the code itself:

      • Its always up-to-date
      • Its always completely consistent with the behavior of the program
      • Its not ambiguous

      Writing clear code is a good thing, and certainly clear code needs less comments than complex code - though the interactions between one bit of clear code and another can still need commenting.

      The best commenting I've seen isn't (of course) the "I'm so tricky, watch this!" style, nor the assembler "add 1 to i" style. The best I've seen not only explained what was going on, it explained the reasoning behind choosing the algorithm(!), what others were tried and why they were rejected, and what possible edge conditions would exist if the environment the code was used in changed and how they could be handled if they ever became possible.

      I've also worked with a great(*) programmer who as the first thing he did when looking at code was strip out every comment. All his variables names were 1 or two characters. He made frequent use of overflows and edge conditions as part of normal operation. His code was tight and very fast (this was image compression/decompression code). It was also close-to-impossible to maintain or debug (yes, I had to). You could read a page of it for hours before figuring out how in hell it produced the right results. For added amusement, when I gave him some modified code to look at, he came back and asked why there was an empty 'else' case. He's stripped the 4 lines of comments from the else that explained why it didn't have to be dealt with.

  388. Only one decent answer to this question! by Anonymous Coward · · Score: 0

    Early optimisation is the root of all evil!

    When programming always try to make the code as explicit and readable as possible.

    Only bother with code optimisations for the very few paths that are actually part of an identified bottleneck.

    A better algorithm is almost always better than bitfucking with an optimiser.

  389. Stupid question by StrawberryFrog · · Score: 1

    what must be hand optimized?"

    Most desktop applications don't need to be optimised.
    Those that do follow the 80-20 rule. They get 80% of the benefit from optimising 20% of the code. Often the ratio is more extreme. Most of the code doesn't need to be optimised.

    When optimising, you won't get much benefit from jerking around with changing "if (!ptr)" to "if (ptr==NULL)". What you need is a whole different approach to the problem. e.g. Searching a list with a for loop? Is the list large and searching more common than insertion? Then it would make sense to sort the list first and use a binary search.

    In conclusion: stupid question, especially from a 10-year coder.

    --

    My Karma: ran over your Dogma
    StrawberryFrog

  390. !p versus p==NULL by jgrahn · · Score: 1
    I sincerely hope noone worries today about a speed difference between those two expressions (if we're talking C here; there is no NULL in C++ or Java). No reasonable compiler would miss that opportunity.

    Personally, I prefer the !p form; I find it is clearer to say "p is an invalid pointer" than saying "p is equal to the the NULL pointer".

    It is interesting to talk about readability vs. optimization, but this example is way too simple to be interesting.

    1. Re:!p versus p==NULL by drxenos · · Score: 1

      ANSI C++ does require the NULL macro to be defined, and required it to be 0.

      --


      Anonymous Cowards suck.
  391. Re:Not always. Check out. by taupter · · Score: 1

    Attention: According to the C ISO standard, NULL is platform dependent. A programmer must not assume NULL=0 if he/she wants to be sure his/her code is portable.

    if(pointer==NULL) may be different from (!pointer).

    if(pointer==NULL) is the correct way to check if the pointer is null, and is the cleanest way to type it.

  392. Re:Not always. Check out. by Anonymous Coward · · Score: 0

    Utter nonsense.
    The REPRESENTATION of NULL might be different from the REPRESENTATION of 0. However, 0 converted to a pointer (usually implicitly through what's called a pointer context), will result in a null pointer in every conforming implementation. The NULL macro is just a convenience that helps readability in some contexts.

  393. Don't worry about the Machine Code by polemistes · · Score: 1
    Code should be intelligent, readable and beautiful. You should not base your code on what you presume the compiler will make of it. Of course, if you know what the compiler will make, it's a bit different. But even then it can be complicated to know what is most effective.

    As an example; I used to programme assembly language on the Amiga 500, a long time ago, with the Motorola 68000 processor. You would presume that doing 'clr a0' should be quicker than 'sub a0,a0', wouldn't you? But after getting hold of a book with the actual cycles an instuction uses, I found out that the previous was quicker. (I hope I remeber the example from '88 correctly...)

    So, my advice is that you optimize you C code as C, not as if it were Assembly Language.

  394. !var is not always the same as var == NULL by flok · · Score: 2, Informative

    Why? There are platforms (maybe there were, not sure) where NULL is actually not the same as 0.

    --

    www.vanheusden.com - home of Multitail, HTTPing, CoffeeSaint, EntropyBroker, rsstail, bsod, listener, nagcon, nagi
    1. Re:!var is not always the same as var == NULL by drxenos · · Score: 1

      How is that imformative?? It's dead wrong!!! Both ANSI C and C++ require that the compiler treat 0 as a null pointer value, regardless of the internal representation used for NULL. They also require that !p and p == NULL BOTH evaluate to true if p is NULL. I'm shocked how many people are writing the same above crap in this thread.

      --


      Anonymous Cowards suck.
  395. visible characters are the root of all evil by hobo2k · · Score: 1


    I prefer to strip all the non-whitespace from my programs.
    </div>

  396. Re:Not always. Check out. by D.+Taylor · · Score: 1
    Sorry, but if (pointer==NULL) is equivalent to if (!pointer).

    See: comp.lang.c FAQ.

    NULL is defined to be (void *)0.
    if (!ptr)
    can be expaded to
    if (ptr != 0)
    .
    Since pointer is, well, a pointer, the compiler can tell implicitly that it needs to compare ptr with a pointer with 0 value, which is defined by the C standard to be NULL.
    However, NULL can be represented physically as non-zero bits, but C programmers should never care -- NULL is defined as (void *)0, so comparisons with 0 in a pointer context are equivalent to comparisons with NULL (whatever the physical representation of NULL is).
  397. optimizing compiler not that smart by Anonymous Coward · · Score: 0

    Most of the optimization are local, which may or may not improve overall performance. Besides, CPUs have their own local optimization for run-time execution.

    If you can find a better algorithm, it's better to replace the whole algorithm than tweaking little things. Eventually CPUs and compilers do better automated jobs with local optimization.

    It is not worth spending time and effort tweaking little things unless small cycle time is important such as in real-time embedded systems. But conventional compilers with good enough embedded processors are enough for non-hard real-time.

  398. Re:Parent is a sicko furry by Anonymous Coward · · Score: 0

    So why not one wearing a fursuit?

  399. You're confused about the C standard by fizbin · · Score: 1
    This is doubly ironic, because the C standard does not guarantee that if (!ptr) has the same result as (ptr != NULL). NULL does not have to be "zero" and on some strange CPUs, it actually is not zero.

    I'll just give you the citation and let you work it out from there: http://www.eskimo.com/~scs/C-faq/s5.html, especially questions 5.3, 5.5, and 5.10.

    The short version: at the level of the C code, NULL is 0 - it has to be. Now, at the assembly language level, the compiler may translate 0 used in a context where it's a pointer to some other value, but at the level of the C source code, it is 0, regardless of CPU. (if it isn't, you're not using C, just some language that mostly looks like C)
  400. Re:Code, Compiler and Optimization by mobiGeek · · Score: 2, Insightful
    As someone else who has been in the industry a long time, I find that only a very small amount of code actually needs to be optimized in the method you mention above.

    The biggest problem I run into are programmers who "know the compiler" so much that they make impossible to decypher all-in-one-if-statement code blobs.

    Write the damn code in a clear and precise way. Compile and run it. If performance is an issue (which for the majority of s/w it is not), then profile the code and make sure you know where the problem is.

    Then, and only then, should the programmer consider rewriting code for optimization. And even then, often it is the algorithm that needs to be fixed, not the fact that the compiler's optimization is missing something obvious. These compiler thingies tend to to be pretty decent these days.

    One of my favourite quotes I share with new grads as they come on-board with their fancy compiler theory classes under belt:

    In "Literate Programming," Donald Knuth wrote "We should forget about small efficiencies, about 97% of the time. Premature optimization is the root of all evil."
    --

    ...Beware the IDEs of Microsoft...

  401. Re:Readibility vs null values by Kell_pt · · Score: 2, Interesting

    Given a pointer to an object, it is not the pointer which is null. The pointer is zero, it is the object which is null, seeing as it is impossible to obtain its value from a pointer with value zero. We just do the trick of using both pointer and its contents to represent incomplete information.

    The concept of NULL is an extension to the domain of a variable. It means "no value". In C/C++, we often think of the pointer as the object itself, and as such we do the little trick of using two different operations to get that valuable extension to the domain: we either read the value of the pointer (a memory address) and compare it to zero or we load its content ( the -> operator ). However, why doesn't one usually compare pointers to static values other than zero( eg, ptr != 3 )? In not doing it, we bring to light the fact that we're just using part of the domain of the pointer variable.
    To make this clear, think of what you'd have to do to have a null integer. In C you'd likely do:
    int * val = malloc( sizeof(int) );
    And then you'd use "val" for the null comparison and "*val" for the integer. Funny how in doing that you're spending more memory than if you did:
    typedef struct { int value; bool isnull; } NullableInt;
    NullableInt a;
    With this you'd spend 5 bytes per variable. With the other approach you spend 4 bytes per variable plus 4 bytes for the pointer, for a total of 8 bytes (on 32 bit architectures). :)

    Obviously, these considerations are a bit pointless, and one benefits little from them in the context of C/C++ programming. :=)

    On the other hand, some languages have specific support for nullable variables, without having to resort to pointers (at least syntactically). NULLs are famous in SQL, although they are also infamous for being used incorrectly many of the times. ;)

    --
    "I don't mind God, it's his fan club I can't stand!" E8
  402. Re:Not always. Check out. by truedfx · · Score: 1

    From the FAQ you linked to:

    [...] the preprocessor macro NULL is #defined (by or ) with the value 0, possibly cast to (void *)

    You're still right about !ptr being equal to ptr != 0 or ptr != NULL, of course.

  403. better code quality by john_uy · · Score: 1

    we are doing a development work (though i am not a programmer but more of a consultant.) i am emphasizing more on better code quality. it is easier to add new equipment to handle the increase load from more operations such as checks rather than modifying software that may potentially cause problems. it is easier to add new equipment than having to redo most of the code due to poor planning. it is easier to add new equipment due to increased load from designing your software to be very compatible to changes and customizations.

    for me, programming is much difficult as it involves too much variables compared to hardware. :) john

    --
    Live your life each day as if it was your last.
  404. Compiler wins by Lars+Clausen · · Score: 2, Insightful

    I go by the First Rule of Optimization: "Don't Do It" (occasionally, I will follow the Second Rule of Optimization: "Don't Do It Yet"). Two reasons:

    1) Hand-optimized code tends to be harder to write, debug, understand, and maintain.
    2) The compiler frequently does a better job anyway. Try comparing the standard strcpy function (while (*s != 0) *t++ = *s++;) with one that uses array indexing (while (s[i] != 0) { t[i] = s[i]; i++; }) using gcc -O3. On some versions and CPUs, the array-indexing code will actually use fewer instructions because the compiler gets more chances for optimization when you tell it that you're working with arrays. Pointer manipulation is for stupid compilers.

    Of course, compilers cannot save you from bad design. Make sure to think about your O() factors.

    -Lars

  405. Re:Trusting the compiler will become very importan by Anonymous Coward · · Score: 0

    I'm guessing they won't be disappointed.

    One word: Itanium.

  406. The FUBAR police by Latent+Heat · · Score: 1
    I see a lot of example programs illustrated with nonsense variable names like foo and foobar.

    My understanding is the the words snafu and foobar (orginally fubar) are acronyms, generated by soldiers during WW-II trying to assert their sanity and individuality within the impersonal bureacracy that is the military.

    Snafu and fubar along with BUFF (the official military designation of the B-52 Stratofortress bomber aircraft) make use of a certain word. Since I am a civilian, I will use the civilian transliteration of the "f" as "fouled", although real military people don't use the civilian transliteration.

    Snafu means "situation normal, all fouled up" and fubar means "fouled-up beyond all repair", while BUFF (a Vietnam-war neologism -- no one called it that in its Cold War role) means "big, ugly, fat, fellow" (OK, a variant on the f-usage.) From my aesthetics of things aviation, the B-52 is large, yes, but I think it is a rather sleek looking aircraft. The "ugly fat fellow" probably refered to the perspective of the enemy at the receiving end of the bomb pattern.

    I had heard of fubar coming to computer usage when the run-time error message on some early FORTRAN systems for divide-by-zero was FUBAR -- the person writing the error message thought that was witty and probably didn't have any supervisor telling them to "clean that up" and "use something more explanatory and professional", and the geek FORTRAN programmers of that day were clean-shaven innocents with pocket pencil protectors who didn't know what fubar means.

    The worst of this is Java example programs with

    FooBar foobar = new FooBar();

    My eyes glaze over when I see nonsense variables, especially in what is meant to be an illustrative example. The variable names can be short, but they should mean something, and is it possible to use Java examples where the class name and the object variable name are differentiated by more than change in case? Could we do

    SampleClass sample_class_inst = new SampleClass()

  407. Re:Parent is a sicko furry by Anonymous Coward · · Score: 0

    fine by me (I'm a different A.C.). just NOT animals.

  408. (+5, original) by thedustbustr · · Score: 1

    Thats funny, your girlfriend blows goats too

    --
    This sig is false.
  409. Wow, mixing logic and computer double speak by tod_miller · · Score: 1

    Programmers deal in logic. Logic has an undeniable complexity. You can only simplify and describe behaviours in certain ways. If you try and re-write it in a way that doesn't reflect the true nature of the system you will certianly introduce bugs later on.

    I believe most systems are programmable in one way, the core system, when you add frills and ui, it explodes into possibilities, but the logic of the system, at key points, it tied to your plan.

    if you plan says that if Y == A, then X *must* == B, then there is a finite way you can code this.

    Compilers on the other hand have to write the best code fo rhtis, again if the compiler is too clever then the window for compiler bugs increases.

    So you shouldn't obfuscate a program to streamline it, as you will no doubt end up loosing this performance later on when you have to work around your constrictive programming.

    practical advice?

    Code predictively, do what the compiler expects. Very eay to do in Java. and of course, always let the compiler optimise.

    Any optimisation of our 'program code' may well actually not translate into optmized object code... as high level languages might allow us to make 'optomized' code lines, but they translate into leg work at lower levels, leg work that reflects the convienience of the higher level of abtraction in your 'optimized code'.

    mmm

    --
    #hostfile 0.0.0.0 primidi.com 0.0.0.0 www.primidi.com 0.0.0.0 radio.weblogs.com
  410. Not because of implicit conversions from void* by jdennett · · Score: 1

    C++ doesn't have implicit conversions from int to pointer (or pointer-to-member-function) types either, however a null pointer constant (which is an integral constant expression evaluating to 0) can be converted to either precisely because of a special rule, which could just as easily apply to (void*)0 as well, making C++ match C in this one case.

    1. Re:Not because of implicit conversions from void* by clarkcox3 · · Score: 2
      which could just as easily apply to (void*)0 as well, making C++ match C in this one case.

      It could, but it doesn't. The following is illegal in C++, period: char * c = (void*)0;

      --
      There are no tiger attacks in my area and it's all because this rock I'm holding keeps the tigers away.
    2. Re:Not because of implicit conversions from void* by jdennett · · Score: 1

      Right, hence "could" rather than "does". The difference is that C has a broader definition of null pointer constant, allowing the zero-valued integral constant expression to be cast to void* -- and my point is that implicit conversions from void* to other pointer types is a red herring.

  411. Re: C's unary negation operators by Anonymous Coward · · Score: 0
    [ Panoplos, I apologize to for choosing your post to reply, but I've bit my tongue on this for two days, and it seems that people are still confused on this issue, so it's time to speak out. ]

    This is for anyone who still does not understand C's unary negation operators. Lesson #1: C has three different unary negation operators: logical (!), bitwise (~) and arithmetic (-).

    • The logical unary negation operator (!, aka not, nz, lneg), accepts integers (signed or unsigned, char, short, int, long, long long and all bitfields based on these), floating point (float, double, long double) and pointers of all sorts; however, it always returns a "boolean" value, which defined as an integer that is either zero or not zero, though by convention most compilers use zero and one. The real-world semantic meaning of this operator is "the opposite logical/boolean value," and is only a reversible operation on boolean (see above) values. Oh yeah. Incidentally, 0.0 and -0.0 are both treated as equal to zero for what should be rather obvious reasons.
      !x == (x == 0), !!x == (x != 0) and !!!x == !x
      A more precise pseudocode for the logical unary negation operator is as follows:
      bool lneg (any x):
      switch (typeof(x)):
      case typeof(integer type T): return x != (T)0;
      case typeof(floating type T): return x != (T)0.0;
      case typeof(typename T*): return x != (T*)0;
      default: throw compiletime_error();
    • The bitwise unary complement/negation operator (~, aka cmpl) accepts only unsigned integers (signed integers are implicitly coerced to unsigned before the operation), and it returns an unsigned integer. This operation reverses ALL of the bits of the given integer. This is a reversible operation for both signed and unsigned integers, since the unsigned result can be coerced back to signed.
      ~x == (x ^ ~0) and ~~x == x
    • The arithmetic unary negation operator (-, aka neg, aneg) in C accepts signed integers (unsigned are silently coerced to signed) and floating point. Its return value is always the same type as the operand, except it is always signed. This is a reversible operation since the return value can be coerced back to unsigned. Be warned that the maximum signed integer value plus one is encoded as the minimum signed integer value; therefore, the negative of the minimum signed integer is itself!
      --x == x

    p.s. C's predication expressions are always logically equivalent to !!x; therefore, you can unambiguously say "if (x)" and the compiler knows you're saying "if (x != 0)". Likewise, the same is true for "while(x)", "for(;x;)" and "(x) ? (a) : (b)". Similarly, you can say "if (!x)", and the compiler knows you're saying "if (x == 0)". People who do not understand C's unary logical negation expressions often mistakenly assume they have to use a binary equivalence relation instead. The submitter appears to have this confusion.

  412. Re: snafoo.... by Anonymous Coward · · Score: 0

    Um I hate to break this to you but CS people know the real meanings of snafu/fubar and choose to use snafoo/foobar because they're funny (to us).

    If you're going to deal with CS types, you're going to have to accept that 'foo' and 'bar' are the two of the most popular temporary/example variable names around. Send any CS major to a whiteboard and ask him/her to use three variables. If you do not specify the purpose of these variables, you will probably get at least foo and bar. Some will mix in stuff like 'bleh', 'blah', 'duh' or 'doh' (though the squares among us often use a,b,c, i,j,k, or x,y,z).

    Use of these variable names almost invariably signifies either (a) code example, (b) confusion/disagreement over requirements or (c) that the code is not production ready.

  413. Break identifiers up! by Monx · · Score: 1

    bool nothanks;

    //do you mean:
    if(nothanks){
    //it doesn't belong to Hank! (Not Hank's)
    }

    //or do you mean:
    if(nothanks){
    //They didn't want any (No Thanks)
    }

    Please break your identifiers apart with underscores or mixed case!

  414. Using plain C is already manually optimising? by marcovje · · Score: 1


    I think using a bare bones language as plain C already comes pretty close to manual optimising.

    In general, for each manual optimisation, a case must be based, preferably based on profiling.
    Optimisation in its own is not bad. The problem is that it is too often done based on perception, and that perception is often down right faulty, or grossly out of date.

  415. use isNull(x) by rkww · · Score: 1

    Use an inline function and let the compiler do the work...

    inline bool isNull(void *x) { return x == 0; }

    if (isNull(ptr)) { ...;
    }

    --
    Roger

  416. VERY different for embedded by Anonymous Coward · · Score: 0

    A LOT of embedded compilers are a LOT dumber than this.

    Big chunks of metaware (a MIPS compiler), for example, appear to be based upon gcc version one.

  417. Re:.NET Has An *Easy* Way for Compiler Optimizatio by PepeGSay · · Score: 1

    Well, since I know .NET and I have used this ability in .NET I can speak to .net.

    Excuse me for trying not to be an expert on everything oh 'god of compilers'. If I had made a mistake on speaking to something else, you guys would be chewing out for a mistake. Now you're chewing me out for being too specific.

    It is a fact that .NET has an easy way to do this.

  418. While we're at it... by ebbe11 · · Score: 1
    As a simple example, take 'if (!ptr)' instead of 'if (ptr==NULL)'

    A better way is:

    if (0==ptr)
    Not all C/C++ compilers have Lint-like features, especially not those used for embedded software. Putting the constant first will transform those nasty unintended assignemnents into syntax errors.
    --

    My opinion? See above.
  419. !ptr is better than ptr == NULL, savvy? by Arch+D.+Bunker · · Score: 1

    void (*ptr)(void); /* .... */
    if (ptr == NULL) /* ... */
    *** cc: error: incompatible types, aborting

    So there probably is a good reason to use "if (!ptr)" after all, especially if you don't know C quite as well as you think you do. Cliches are cliches for some very good reasons ...

  420. Re:Clear Code (FP pedant) by Steveftoth · · Score: 1

    a) The Compiler actually doesn't infer the correct type most of the time but usually takes the literal and type converts it. Usually at compile time, but not always.

    b) Nowhere did you say
    float var = 0.0f;
    System.println(var); //prints infinity.

    Since if that were true, then how in the world would he code you posted work? Was it a bug in the way that the PrintStream wrote the float? That might to have been the problem.

    How did you know that the value of your float was exactly 0.0f (that number is representable in IEEE floating point)?

  421. Floating point code by devillion · · Score: 1

    Compiler cannot reorder or do other optimizations with floating point code without potentially breaking something.

  422. Re:if (var = NULL) by Anonymous Coward · · Score: 0

    If this compiles, then the first thing you do is look at the compiler documentation, and choose a combination of compiler flags that stops it from compiling. if (var = NULL) will produce a warning on any decent compiler unless some really exceedingly dumb programmer has switched that warning on, and any decent compiler can be convinced not to accept code that gives any warnings.

    If you can't convince your compiler not to accept if (var = NULL) then it is time to look for a different compiler.

  423. Re:Clear Code (FP pedant) by 3.1415926535 · · Score: 1

    b) Nowhere did you say
    float var = 0.0f;
    System.println(var); //prints infinity.


    Dude...

    If you try to print a float who's value is exactly 0.0f, it would print "infinity" instead.

    I knew it was exactly 0.0f because somewhere earlier in the program I set it to that. The bug was definitely in the Metrowerks runtime. The code I posted worked fine because if the var was 0.0f it would print "0", and if it wasn't, then the runtime worked fine. I'm going to stop replying to this pointless thread now.

  424. Optimization doesn't always mean what we think. by Anonymous Coward · · Score: 0

    Hm, a few thoughts:

    1. As your normal style, choose both clear and "fast".

    Any optimizer worth its salt will give you nice, fast assembly for if(pointer) and if(0 == pointer) and if(!pointer), and if(NULL == pointer), and... you get the idea. Choosing one of these over the other is something of a holy war, but I'd say that you should here, as in most cases, pick what's easiest to read and don't sweat the details. That will be the least of your performance woes. Compilers really do a nice job handling this sort of thing. Choosing between for and while on some (usually old) platforms can make a (minor) difference, but again, don't we have better things to do?

    So, what should be avoided?

    You can find a lot of guidelines for avoiding the construction of code that is slower than it needs to be from "go"-- for example, use pointers when you can, they tend to be "fast". You can also use array indices. Fine.

    But avoid duplicating data, setting sentinel values, needlessly traversing and/or doing compares that are redundant on your data sets, etc.. Your compiler probably just won't have any way of helping you there.

    Those are the kinds of performance-impacting things that are in the programmer's hands-- usually, just let the compiler sort out the opcodes, you have bigger problems.

    Watch what your algorithms are doing, and watch how many passes through the same data they make.

    2. Measure.

    You can waste a lot of time fiddling with the wrong parts of your program. Always ask yourself "is the problem that my function is slow, or is the problem that it's for some reason being called a zillion times". If it's being called a zillion times, "does it need to be"? If it's slow "why"? I've wasted a lot of time by not doing this, and I've saved a lot of time by doing it.

    3. Solve the Right Problem.

    Coming back to topic [1], passing data around and doing type conversion is slow-- and the compiler can't help you with it. So if you have unintentionally (or intentionally) gotten into a situation when you need to do numeric comparisons on strings, try to find a way to make it all integer, or at least reduce the number of conversions. This doesn't usually happen in languages with reasonable typing systems, thankfully, but happens all the time in languages that do a great deal of implicit type or even data conversion (figuring out which ones and in what cases is left as an excercise to the reader-- this isn't usually bad, they save you development time by doing this (well, okay, maybe not as much as we sometimes think...)).

    The bottom line is that you should be using appropriate types and data for the operations you are performing.

    (Note: Good use of parameterized types (some languages use "templates" for this) can help with this problem... a lot.)

    How much of a difference can this make, and why am I spending so much time on it? Well again, without getting into specifics, on a recent project I improved a function's performance by about 500 times simply by rewriting it in another language. But then I had a mini-epiphany, and changed the way it worked so that the data and types agreed more closely... this was about a 35 /thousand/ time improvement. No kidding.

    While few results are (hopefully) likely to be so dramatic, the principle is a good one to bear in mind, I think.

    3.5. "Premature Optimization is the Root of All Evil".

    See [2] "measure". :-)

    (P.S.-- the guy to whom that quote is attributed knows a thing or two about the subject at hand.)

    4. If the compiler can't do better than you can, it's time to optimize.

    There are some cases where you can write better assembly code than the compiler. If you know when those are, you probably didn't need to read this though, did you? ;>

  425. Know what you need to optimize first by rfc1394 · · Score: 1
    There is no point in optimizing a piece of code that never gets executed. There is little point in optimizing a piece of code that takes 2 seconds longer than it should when it's only executed once in 100,000 executions. You need to know what code is being executed how often, then when you find out what code is being executed the most, find where the code has the bottlenecks that reduce performance, and you target those points for optimization.

    It's said in real estate the three most important things are Location, Location, Location. Well, it seems, it's true in optimization too.

    On second thought, the three most important things in optimization are Measure, Measure, Measure. You need to measure before you can optimize. If you don't measure, you don't know what really needs to be optimized. You have to profile to properly optimize.

    Anything else wastes valuable time. Unless you optimize the parts that are executed the most or which slow down the process the worst, you are "very efficiently wasting time."

    --
    The lessons of history teach us - if they teach us anything - that nobody learns the lessons that history teaches us.
  426. Complexity by DimGeo · · Score: 1

    What programmers should mainly worry about today is speed and size complexity, not some cheap tricks IMHO. Of course, it depends on the compiler. If it is a promptly hacked together embedded C compiler with no optimization options, you might wish to be much, much more careful about what you are doing. Otherwise, happily use whatever you need, and let the compiler worry about the tiny details.