• Post Your Nifty Programming Tips n' Tricks
    55 replies, posted
[b]Post your useful programming tips that makes your code look good, perform better, makes your life easier or just any tips that you use regularly.[/b] When using the operators ++ or --, make it a habit to use the operator before the variable when ever possible. Instead of [code] i++; [/code] use [code] ++i; [/code] It will save you 1 or 2 CPU cycles, thus making your code almost unnoticeably faster! It can be noticeable if you have massive for-loops in your code.
You completely missed the point.
[QUOTE=Rocket;32702717]Heh, no.[/QUOTE] Hm. [code] sys::Stopwatch sw; while(1) { sw.Reset(); sw.Start(); for(unsigned long long i = 0; i < 1000000000uL; i++); sw.Pause(); sys::Dbg::Printf("\nA: %i", sw.ElapsedMS()); sw.Reset(); sw.Start(); for(unsigned long long i = 0; i < 1000000000uL; ++i); sw.Pause(); sys::Dbg::Printf("\nB: %i", sw.ElapsedMS()); } [/code] [code] A: 3179 B: 3045 A: 3125 B: 3030 A: 3154 B: 3040 A: 3152 B: 3073 A: 3149 B: 3094 A: 3145 B: 3057 A: 3166 B: 3111 A: 3716 B: 3266 [/code] edited: even wrapped it in a while loop
[QUOTE=Rocket;32703062]I'm not talking about how fast it is, if you use one instead of the other, it might change the way your code operates.[/QUOTE] oh. [QUOTE=ief014;32701954]make it a habit to use the operator before the variable [b]when ever possible[/b].[/QUOTE]
[QUOTE=Rocket;32703062]I'm not talking about how fast it is, if you use one instead of the other, it might change the way your code operates.[/QUOTE] Well, we ARE talking about how fast it is. And if you're using it in an assignment you already ought to know the difference between the two.
In C# you can (even should) use the using statement to automatically free resources at the end of a logical block, instead of .Dispose() Example1 explains what I mean [URL]http://www.dotnetperls.com/streamreader[/URL] Also: Only optimize when there is a problem with performance AND you are already using the best algorithm / data structures for the job. Getting it done is almost always more important than making the program faster...
[QUOTE=ief014;32702892]Hm. [code] sys::Stopwatch sw; while(1) { sw.Reset(); sw.Start(); for(unsigned long long i = 0; i < 1000000000uL; i++); sw.Pause(); sys::Dbg::Printf("\nA: %i", sw.ElapsedMS()); sw.Reset(); sw.Start(); for(unsigned long long i = 0; i < 1000000000uL; ++i); sw.Pause(); sys::Dbg::Printf("\nB: %i", sw.ElapsedMS()); } [/code] [code] A: 3179 B: 3045 A: 3125 B: 3030 A: 3154 B: 3040 A: 3152 B: 3073 A: 3149 B: 3094 A: 3145 B: 3057 A: 3166 B: 3111 A: 3716 B: 3266 [/code] edited: even wrapped it in a while loop[/QUOTE] Sounds like you have a shitty compiler. In cases where the prefix and postfix operators are interchangeable, a good compiler should emit the same instructions. Also, those 'for' loops shouldn't be executing at all. They don't do anything, so a good compiler would throw them out entirely.
[QUOTE=ief014;32701954][b]Post your useful programming tips that makes your code look good, perform better, makes your life easier or just any tips that you use regularly.[/b] When using the operators ++ or --, make it a habit to use the operator before the variable when ever possible. Instead of [code] i++; [/code] use [code] ++i; [/code] It will save you 1 or 2 CPU cycles, thus making your code almost unnoticeably faster! It can be noticeable if you have massive for-loops in your code.[/QUOTE] Depends entirely on the type, language, optimizations, etc. The example you gave, in C# gets compiled into the same thing. [editline]9th October 2011[/editline] [QUOTE=Felheart;32703368]In C# you can (even should) use the using statement to automatically free resources at the end of a logical block, instead of .Dispose() Example1 explains what I mean [URL]http://www.dotnetperls.com/streamreader[/URL] Also: Only optimize when there is a problem with performance AND you are already using the best algorithm / data structures for the job. Getting it done is almost always more important than making the program faster...[/QUOTE] Well 'using' is just sugar for disposing. [csharp]using (object) { //Use it here }[/csharp] becomes [csharp]try { //Use it here } finally { object.Dispose(); }[/csharp] Which the finally block is always called, even if an uncaught exception is thrown. That way it is always disposed. While on the subject, [URL="http://msdn.microsoft.com/en-us/library/fs2xkftw.aspx"]implementing dispose[/URL] correctly is very important.
[QUOTE=ROBO_DONUT;32704331]Sounds like you have a shitty compiler. In cases where the prefix and postfix operators are interchangeable, a good compiler should emit the same instructions. Also, those 'for' loops shouldn't be executing at all. They don't do anything, so a good compiler would throw them out entirely.[/QUOTE] Microsoft VC++ 2008 Compiler. No optimizations enabled. Sure, a compiler *should* do the same thing, but it should be a good practice and you shouldn't trust the compiler.
[QUOTE=ief014;32705138]Microsoft VC++ 2008 Compiler. No optimizations enabled. Sure, a compiler *should* do the same thing, but it should be a good practice and you shouldn't trust the compiler.[/QUOTE] I honestly don't even know where to start here. First, I've been pretty outspoken about how awful I think MSVC is. This merely reinforces that point. More importantly, this is so far beyond 'premature optimization' that I can't even put my dismay into words. If your program does not have [i]hard[/i] real-time constraints (i.e. catastrophic failure results if you don't respond to some interrupt within x number of microseconds), then you don't benefit at all from worrying about all these little nitpicky details that give you a 0.0001% performance boost. Second, if you do have such a constraint, and you're forced to account for stupid compiler-specific quirks to make it happen, you should just give up and write it in assembly. Also, there is absolutely no technical reason what-so-ever why one should be faster than the other for the general case. If it's prefix is faster on one compiler, then postfix is likely faster on some other compilers. It doesn't make sense to prefer one over the other when you can't even predict which will be faster.
[QUOTE=ROBO_DONUT;32705208]I honestly don't even know where to start here.[/QUOTE] Is it really that terrible to place the increment operators before the variable when possible for possibly a little more speed? The reason I disabled optimizations was to prove exactly what it was doing. I don't see the problem at all.
Personally, I prefer: [code] int a=0; for(int i=0;i<10000000000;i=i/1+1){ if(i%2==0){ a=a+1 }else{ a=a-1 } } [/code]
[QUOTE=ief014;32705257]Is it really that terrible to place the increment operators before the variable when possible for possibly a little more speed? The reason I disabled optimizations was to prove exactly what it was doing. I don't see the problem at all.[/QUOTE] Made some edits that explain everything that is wrong with that logic. [QUOTE=Map in a box;32705291] int a=0; for(int i=0;i<10000000000;[b]i=i/1+1[/b]){ if(i%2==0){ a=a+1 }else{ a=a-1 } }[/QUOTE] ??
[QUOTE=ROBO_DONUT;32705208]Also, there is absolutely no technical reason what-so-ever why one should be faster than the other for the general case. If it's prefix is faster on one compiler, then postfix is likely faster on some other compilers. It doesn't make sense to prefer one over the other when you can't even predict which will be faster.[/QUOTE] One may be faster than the other because the different operators do different things. i++; Stores a temporary variable and puts the older value of i into that value, then increases i by one. ++i; Simply increases i by one. Seriously, this shit is what happens when I try to help people. a++ thread [editline]9th October 2011[/editline] sorry, I mean ++a thread
[QUOTE=ief014;32705758]One may be faster than the other because the different operators do different things.[/QUOTE] If you can choose which one to use, then they're interchangeable, and they do [i]exactly the same thing[/i]. In cases where they're not interchangeable, your entire point is moot because you have no choice in the matter. [QUOTE=ief014;32705758]Seriously, this shit is what happens when I try to help people. a++ thread.[/QUOTE] It wasn't my intent to discourage you from trying to help people.
[QUOTE=ROBO_DONUT;32705971]"[this or that] is good practice" are fighting words, and you need to be absolutely sure about what you're saying before advocating a specific approach.[/QUOTE] I research my shit all the time to make sure I'm not skimping on anything. [QUOTE=ROBO_DONUT;32705971]If you can choose which one to use, then they're interchangeable, and they do [i]exactly the same thing[/i]. In cases where they're not interchangeable, your entire point is moot because you have no choice in the matter.[/QUOTE] In a way, they do perform the same thing in the end, but they are not [i]exactly[/i] the same; [QUOTE=ief014;32705758]i++; Stores a temporary variable and puts the older value of i into that value, then increases i by one. ++i; Simply increases i by one.[/QUOTE] [url]http://www.google.ca/search?gcx=w&sourceid=chrome&ie=UTF-8&q=is+preincrement+faster+than+postincrement[/url] Perhaps I am going over my head just to achieve those extra picoseconds, but it's something I never knew about until recently and I thought it was neat enough that everyone should know about.
[QUOTE=ief014;32706067]I research my shit all the time to make sure I'm not skimping on anything.[/QUOTE] Regardless of what your research tells you, these little micro-optimizations are most certainly bad practice. You won't gain any measurable benefit in performance and, in more extreme cases, you risk wasting development time or writing idiosyncratic code. Again, I don't mean to be an ass, but this is something I've learned by experience. This is a mistake that I think just about every new programmer makes, and it's best if it isn't reinforced in any way. [QUOTE=ief014;32706067]In a way, they do perform the same thing in the end, but they are not [i]exactly[/i] the same; [url]http://www.google.ca/search?gcx=w&sourceid=chrome&ie=UTF-8&q=is+preincrement+faster+than+postincrement[/url] Perhaps I am going over my head just to achieve those extra picoseconds, but it's something I never knew about until recently and I thought it was neat enough that everyone should know about.[/QUOTE] You are looking at this from a fuzzy high-level textbook standpoint instead of realizing that human-readable source code is just an intermediary language. The compiler can do whatever it damn well pleases as long as it produces the same result. This includes everything from simplifying code in whatever way it can at compile time to stuff like re-arranging instructions to dodge pipeline hazards. Also note that while I say things like "simplifying code", it's really not represented internally as anything remotely resembling the original code for most compilers. They try to extract the "logic" from the words and often build an abstract tree-like structure in the process. Simple information like whether the prefix or postfix operator was used in the original code probably gets lost (I'm not a compiler expert, but I don't see any reason to store this), and a general-purpose "increment" gets stuck in either one part of the tree or another.
[QUOTE=ROBO_DONUT;32706228]Regardless of what your research tells you, these little micro-optimizations are most certainly bad practice. You won't gain any measurable benefit in performance and, in more extreme cases, you risk wasting development time or writing idiosyncratic code. Again, I don't mean to be an ass, but this is something I've learned by experience. This is a mistake that I think just about every new programmer makes, and it's best if it isn't reinforced in any way.[/QUOTE] I'm not encouraging people, especially new programmers, to go through their entire code replacing all their "i++" to "++i". In my experience as well, I know that sometimes these little things are just not worth worrying about. Again, it's just something nifty I discovered a while ago, and it is not bad that it becomes a habit.
I have the habit of using prefix operators ALL THE TIME, as postfix operators have side effects that aren't immediately obvious to most programmers, leading to confusing as to why code works a certain way. Of course, that's not because of performance. If I really care about how many clock cycles I save on my 8 CPUs that do 2660000000 cycles a second, I'll be rewriting my code to work better. Anyway, my biggest influence on how I program, and which results in my code being completely understandable after months of not looking at it (even if I'll be the only one looking at it), "Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live" - Martin Golding
[QUOTE=ief014;32706479]I'm not encouraging people, especially new programmers, to go through their entire code replacing all their "i++" to "++i".[/QUOTE] [QUOTE=ief014;32701954]make it a habit to use the operator before the variable when ever possible.[/QUOTE]
How is habit the same as going through your whole code and modifying increments?
AFAIK with primitive types there shouldn't be any difference, but with custom types like iterators it could make a difference because of the way they're programmed. I use postifx for primitives and prefix for iterators.
[QUOTE=ief014;32705138]Microsoft VC++ 2008 Compiler. No optimizations enabled.[/QUOTE] [QUOTE=ief014;32705257]The reason I disabled optimizations was to prove exactly what it was doing.[/QUOTE] Hang on, what the hell do you expect it to do when you tell it not to optimise ? Part of its optimisation is to replace sections of code with a faster equivalent. I really fail to see what point you're trying to make with this thread. Using ++x everywhere possible should be no faster than using x++ with compiler optimisation turned on. In fact I'd bet it would be slower as the programmer would go out of their way to turn x++ into ++x. If you micro-optimise these things, it makes it much harder for the compiler to do its optimisation, which by the way it can do far better than any human can manually in the vast majority of cases.
"Premature optimization is the root of all evil" I see what you're getting at, but seriously, any optimiser is going to output exactly the same for both. The only time it wouldn't, would be if it mattered whether the increment happens before or after the operation (in which case you don't have choice). For a for loop increment, it doesn't make a difference so use what you like. Yes it makes a difference when it isn't optimised, but if you're worrying about an extra operation or two, then just optimise it. A tip I'd give is to write readable code, make sure that it makes sense, then run it through a decent compiler. Start with something that works, then worry about the tiny details later. Optimisers are a lot more clever than you might think. I work with a guy who fills his code with horrendous little tricks (and worse, abbreviated variable names *shudder*), but all they succeed in doing is making his code completely unreadable. We dread getting a bug report about the text rendering in our software, because we know that it will mean half a day's work before we start, just going back through his code trying to understand it. Just avoid making your code confusing and the optimiser can work out how to make it into nice fast binary.
It doesn't even have anything to do with compiler optimization. If you can directly substitute x++ with ++x or vice-versa, then there's [i]literally no difference in meaning[/i]. Most processors have only one instruction for increment/decrement. The only difference is in the order in which the parts of the expression are evaluated. When the result isn't used, the order doesn't matter either, and they're exactly the same. It's not like writing one or the other should produce different instructions, even without optimization. GCC without optimization emits the same assembly code for ++x; and x++;. [editline]10th October 2011[/editline] [QUOTE=Jookia;32709590]I have the habit of using prefix operators ALL THE TIME, as postfix operators have side effects that aren't immediately obvious to most programmers, leading to confusing as to why code works a certain way.[/QUOTE] IIRC, the postfix operators don't have any side-effects that the prefix operators don't also share.
Will you guys stop talking about this i++ and ++i bullshit and post some programming tips already? For C#, here's a whole list of cool hidden stuff you probably haven't seen before: [url]http://stackoverflow.com/questions/9033/hidden-features-of-c[/url]
[QUOTE=ROBO_DONUT;32713065]IIRC, the postfix operators don't have any side-effects that the prefix operators don't also share.[/QUOTE] It returns the previous non-incremented value, rather than the incremented value. This can lead to some hairy bugs when you do something like: editEntry(index++, ...)
[QUOTE=Jookia;32713574]It returns the previous non-incremented value, rather than the incremented value. This can lead to some hairy bugs when you do something like: editEntry(index++, ...)[/QUOTE] Right, but that's the entire point of the postfix operator, not really a 'side-effect'.
Can somebody rename this thread to "Discuss postfix and prefix increment operators"
Alright children, I'm sorry that I told you about the differences between prefix and postfix operators. Can we please just move on now? It's really not that big of a deal.
Sorry, you need to Log In to post a reply to this thread.