473,405 Members | 2,310 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,405 software developers and data experts.

C# very optimisation

hi,

do you know where i can find some ebooks or websites talking about C#
optimisation ?

for exemple, i just learned that ++i is faster than i++. i would like to
know more about the things that can make code faster than fast.

thank you.
Nov 17 '05 #1
55 3650
Ennixo <en****@free.fr> wrote:
do you know where i can find some ebooks or websites talking about C#
optimisation ?

for exemple, i just learned that ++i is faster than i++.
In C#? I don't think so. It *can* be faster in *some* languages, but
it's rarely going to make a significant difference.
i would like to
know more about the things that can make code faster than fast.


Proper design and profiling when necessary, basically. Micro-
optimisations rarely make a significant difference to overall
performance - even if tweaking your code makes one section of code five
times faster, unless a significant amount of time is spent in that part
of the code, it's not going to make much difference. Obviously it
depends on the app, but in many apps these days the most significant
performance bottlenecks come from things like network/database access,
bad choice of threading, etc.

Furthermore, micro-optimisations tend to come at the expense of the
code being as readable as it can be, which IMO should be the primary
goal.

If your app isn't performing well enough, get a profiler and find out
exactly where the bottleneck is. At that point, and only at that point,
should you be really worried about micro-optimisations.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 17 '05 #2
Jon Skeet [C# MVP] a écrit :
Furthermore, micro-optimisations tend to come at the expense of the
code being as readable as it can be, which IMO should be the primary
goal.


generaly yes, but this is for image processing, so i need to optimize as
much as i can, even if the code becomes 10x bigger and unreadable
Nov 17 '05 #3
When talking about image processing, a VERY big performance bonus can be
gained when using unmanaged (unsafe) code and pointers. I remember an
article saying unmanaged image processing can be up to 28 times faster than
managed.
Here it is
http://tinyurl.com/3sux8
"Ennixo" <en****@free.fr> wrote in message
news:42*********************@news.wanadoo.fr...
Jon Skeet [C# MVP] a écrit :
> Furthermore, micro-optimisations tend to come at the expense of the
code being as readable as it can be, which IMO should be the primary
goal.


generaly yes, but this is for image processing, so i need to optimize as
much as i can, even if the code becomes 10x bigger and unreadable

Nov 17 '05 #4
Lebesgue a écrit :
When talking about image processing, a VERY big performance bonus can be
gained when using unmanaged (unsafe) code and pointers. I remember an
article saying unmanaged image processing can be up to 28 times faster than
managed.
Here it is
http://tinyurl.com/3sux8


Thank you, i already use unsafe for my processing of course but i would
like to know more about little optimisations now (juste like "++i"
instead of "i++")

but i will read MSDN's unsafe image processing page because i never saw
it before =)
Nov 17 '05 #5
>
Thank you, i already use unsafe for my processing of course but i would
like to know more about little optimisations now (juste like "++i" instead
of "i++")


++i and i++ is not the same if used within things like calling methods and
stuff like that.

Is the one considered faster than the other ?

--
Søren Reinke
www.Xray-Mag.com/ - Your free diving magazin on the net.
Current issue Diving in North America, 99 pages.
Download it in PDF
Nov 17 '05 #6
> for exemple, i just learned that ++i is faster than i++. i would like to
know more about the things that can make code faster than fast.


Where did you read that? There shouldn't be any difference from the
generated code performance.

However, in C# there are similar rules for performance like it is in C++.
The basics in C# are avoiding boxing and use StringBuilder instead of
strings but that shouldn't be useful for image processing anyway.

Nov 17 '05 #7
cody a écrit :
Where did you read that? There shouldn't be any difference from the
generated code performance.


i read it in a source code from csharpfr.com and i saw it in some
sources of codeproject.com
Nov 17 '05 #8
Søren Reinke wrote:
Thank you, i already use unsafe for my processing of course but i would
like to know more about little optimisations now (juste like "++i" instead
of "i++")

Try a profiler, and optimize the places when processing time is actually
used. That way your optimizations may actually matter instead of just
waste your time and make the code unreadable.
++i and i++ is not the same if used within things like calling methods and
stuff like that.
more precicely, ++i and i++ are not the same when used as an expression.
Is the one considered faster than the other ?


When defining your own "operator++" the x++ variant needs to copy the
old object, ++x does not.

I can't imagine that there is *any* difference whatsoever for the
performance using ++i or i++ (esp. on integral types), and will continue
to think that untill I see a test-program proving otherwise.

--
Helge Jensen
mailto:he**********@slog.dk
sip:he**********@slog.dk
-=> Sebastian cover-music: http://ungdomshus.nu <=-
Nov 17 '05 #9

"Ennixo" <en****@free.fr> wrote in message
news:42***********************@news.free.fr...
cody a écrit :
Where did you read that? There shouldn't be any difference from the
generated code performance.


i read it in a source code from csharpfr.com and i saw it in some sources
of codeproject.com


I don't think it matter at all.i++ og ++i just add's 1 to the variable.

But if you have some documentation about it i would love to see it.

--
Søren Reinke
www.Xray-Mag.com/ - Your free diving magazin on the net.
Current issue Diving in North America, 99 pages.
Download it in PDF
Nov 17 '05 #10
Helge Jensen a écrit :
I can't imagine that there is *any* difference whatsoever for the
performance using ++i or i++ (esp. on integral types), and will continue
to think that untill I see a test-program proving otherwise.


so try this sample code (paste in Main method) and you will think that
++i is really faster than other ways to increment by 1. (note: run in
RELEASE mode)

DateTime d;
TimeSpan t;
int iMax = 1000000000;
int j;

// Test 1 : i++
j = 0;
d = DateTime.Now;
for (int i = 0; i < iMax; i++)
j += i;
t = DateTime.Now - d;
Console.WriteLine("i++ : {0}", t.TotalMilliseconds.ToString());
// Test 2 : ++i
j = 0;
d = DateTime.Now;
for (int i = 0; i < iMax; ++i)
j += i;
t = DateTime.Now - d;
Console.WriteLine("++i : {0}", t.TotalMilliseconds.ToString());

// Test 3 : i += 1
j = 0;
d = DateTime.Now;
for (int i = 0; i < iMax; i += 1)
j += i;
t = DateTime.Now - d;
Console.WriteLine("i += 1 : {0}", t.TotalMilliseconds.ToString());
// Test 4 : i = i + 1
j = 0;
d = DateTime.Now;
for (int i = 0; i < iMax; i = i + 1)
j += i;
t = DateTime.Now - d;
Console.WriteLine("i = i + 1 : {0}", t.TotalMilliseconds.ToString());
Console.Read();
Nov 17 '05 #11

"Ennixo" <en****@free.fr> wrote in message
news:42***********************@news.free.fr...
Helge Jensen a écrit :
I can't imagine that there is *any* difference whatsoever for the
performance using ++i or i++ (esp. on integral types), and will continue
to think that untill I see a test-program proving otherwise.


so try this sample code (paste in Main method) and you will think that ++i
is really faster than other ways to increment by 1. (note: run in RELEASE
mode)


Sorry to say but no difference worth mentioning, sometimes the one is faster
sometimes the other.

Run #1
i++ : 5167,4304
++i : 5107,344
i += 1 : 5047,2576
i = i + 1 : 5087,3152
Run #2
i++ : 5037,2432
++i : 5117,3584
i += 1 : 5067,2864
i = i + 1 : 5067,2864
Run #5
i++ : 5047,2576
++i : 5117,3584
i += 1 : 5037,2432
i = i + 1 : 5127,3728
Run #4
i++ : 5127,3728
++i : 5107,344
i += 1 : 5027,2288
i = i + 1 : 5077,3008
--
Søren Reinke
www.Xray-Mag.com/ - Your free diving magazin on the net.
Current issue Diving in North America, 99 pages.
Download it in PDF
Nov 17 '05 #12
It is not just an optimization to use ++i instead of i++, although that is
established. It is for readability. Using i++ means you need the value of i
before it has been incremented. Using ++i simply means: increment. So by
using i++ where you don't need it, you are making code less readable. It is
good practice to use ++ correctly.

Regards,
Frank Hileman

check out VG.net: http://www.vgdotnet.com
Animated vector graphics system
Integrated Visual Studio .NET graphics editor
"Helge Jensen" <he**********@slog.dk> wrote in message
news:%2****************@TK2MSFTNGP15.phx.gbl...
Søren Reinke wrote:
Thank you, i already use unsafe for my processing of course but i would
like to know more about little optimisations now (juste like "++i"
instead of "i++")


Try a profiler, and optimize the places when processing time is actually
used. That way your optimizations may actually matter instead of just
waste your time and make the code unreadable.
++i and i++ is not the same if used within things like calling methods
and stuff like that.


more precicely, ++i and i++ are not the same when used as an expression.
Is the one considered faster than the other ?


When defining your own "operator++" the x++ variant needs to copy the old
object, ++x does not.

I can't imagine that there is *any* difference whatsoever for the
performance using ++i or i++ (esp. on integral types), and will continue
to think that untill I see a test-program proving otherwise.

--
Helge Jensen
mailto:he**********@slog.dk
sip:he**********@slog.dk
-=> Sebastian cover-music: http://ungdomshus.nu <=-

Nov 17 '05 #13
Ennixo wrote:
so try this sample code (paste in Main method) and you will think that
++i is really faster than other ways to increment by 1. (note: run in
RELEASE mode)


No, I will not. try rearranging the order of the executed statements.
Lots of things are going on behind your back in the .NET runtime.

To resolve this matter once and for all, here is an example test function:
class Test
{
public static void test(uint iterations)
{
int j = 0;
for ( uint i = 0; i < iterations; ++i )
j += j;
for ( uint i = 0; i <iterations; i++ )
j += j;
}
}

If i translate this in release-mode and apply ildasm to disassemble i
get the code below (my comments). The code is *exactly* the same for the
++i and i++ loops.

..method public hidebysig static void test(unsigned int32 iterations)
cil managed
{
// Code size 35 (0x23)
.maxstack 2
.locals init ([0] int32 j,
[1] unsigned int32 i,
[2] unsigned int32 V_2)
// here comes loop with ++i
IL_0000: ldc.i4.0 // ->0
IL_0001: stloc.0 // j = (0)
IL_0002: ldc.i4.0 // ->0
IL_0003: stloc.1 // i1 = (0)
IL_0004: br.s IL_000e //
IL_0006: ldloc.0 // ->j
IL_0007: ldloc.0 // ->j
IL_0008: add // ->(j+j)
IL_0009: stloc.0 // j = (j+j)
IL_000a: ldloc.1 // ->i1
IL_000b: ldc.i4.1 // ->1
IL_000c: add // ->(i1+1)
IL_000d: stloc.1 // i1 = (i1+1)
IL_000e: ldloc.1 // ->i1
IL_000f: ldarg.0 // ->iterations
IL_0010: blt.un.s IL_0006 // if (i1 != iterations) goto IL_0006
// here comes loop with i++
IL_0012: ldc.i4.0 // -> 0
IL_0013: stloc.2 // i2 = (0)
IL_0014: br.s IL_001e // goto IL_001E
IL_0016: ldloc.0 // -> j
IL_0017: ldloc.0 // -> j
IL_0018: add // ->(j+j)
IL_0019: stloc.0 // j = (j+j)
IL_001a: ldloc.2 // -> i2
IL_001b: ldc.i4.1 // -> 1
IL_001c: add // ->(i2+1)
IL_001d: stloc.2 // i2=(i2+1)
IL_001e: ldloc.2 // -> i2
IL_001f: ldarg.0 // -> iterations
IL_0020: blt.un.s IL_0016 // if (i2 != iterations) goto IL0016
IL_0022: ret // return
} // end of method Test::test

--
Helge Jensen
mailto:he**********@slog.dk
sip:he**********@slog.dk
-=> Sebastian cover-music: http://ungdomshus.nu <=-
Nov 17 '05 #14
Frank Hileman wrote:
It is not just an optimization to use ++i instead of i++, although that is
It is not an "optimization" in .NET, or on any integral type of any
C/C++-compiler I know of.
established. It is for readability. Using i++ means you need the value of i
before it has been incremented. Using ++i simply means: increment. So by
No, "++i" and "i++" are *both* expressions. "i = i + 1" and "i += 1",
are statements. Using "++i" as a statement is equivalent to "i = i + 1",
or "i += 1".

Remember that the syntax of "for" is

'for' '(' STMT ';' EXPR ';' STMT ')' BLOCK_OR_STMT

not:

'for' '(' STMT ';' EXPR ';' EXPR ')' BLOCK_OR_STMT

So we should really be writing:

for ( int i = 0; i < limit; i += 1 )

otherwise you are discard the value of an expression.

but since the dawn of time C-programmers have preferred the (1 character
shorter) "i++" to "i+=1". There have *never* *ever* been *any*
performance-reason for this.

I C++ you have overloadable operator++, and this means that you *can*
construct classes where the left++ is cheaper than the right++,
therefore you see C++ programmers do:

for ( IT it = begin; it != end; ++it )

which *may* yield better performance in *rare* cases (the optimizer
solves most simple cases).
using i++ where you don't need it, you are making code less readable. It is
good practice to use ++ correctly.


Which is not really much except in indexing in loops:

public void CopyTo(Array a, int index)
{ foreach ( object o in this ) a.SetValue(o, index++); }

that i prefer to:

public void CopyTo(Array a, int index)
{
foreach ( object o in this )
{
a.SetValue(o, index);
index += 1;
}
}
--
Helge Jensen
mailto:he**********@slog.dk
sip:he**********@slog.dk
-=> Sebastian cover-music: http://ungdomshus.nu <=-
Nov 17 '05 #15
very strange, i always have these results (with very little variation)
i++ : 4600
++i : 3900
i += 1 : 4600
i = i + 1 : 4600

Søren Reinke a écrit :
"Ennixo" <en****@free.fr> wrote in message
news:42***********************@news.free.fr...
Helge Jensen a écrit :

I can't imagine that there is *any* difference whatsoever for the
performance using ++i or i++ (esp. on integral types), and will continue
to think that untill I see a test-program proving otherwise.


so try this sample code (paste in Main method) and you will think that ++i
is really faster than other ways to increment by 1. (note: run in RELEASE
mode)

Sorry to say but no difference worth mentioning, sometimes the one is faster
sometimes the other.

Run #1
i++ : 5167,4304
++i : 5107,344
i += 1 : 5047,2576
i = i + 1 : 5087,3152
Run #2
i++ : 5037,2432
++i : 5117,3584
i += 1 : 5067,2864
i = i + 1 : 5067,2864
Run #5
i++ : 5047,2576
++i : 5117,3584
i += 1 : 5037,2432
i = i + 1 : 5127,3728
Run #4
i++ : 5127,3728
++i : 5107,344
i += 1 : 5027,2288
i = i + 1 : 5077,3008

Nov 17 '05 #16
Everyone seems to be missing the important point about ++i vs i++
optimization...

Namely it comes in play mostly on user defined types with an overload
operator ++.

You're just not going to see the difference using an int.

To understand this, imagine we have a class (MyClass), which has a
member function (AddOne), and we want to implement op++ and ++op. (For the
moment, I'm going to do this in C++)

class MyClass
{
public:
void AddOne() {.....}

// The Pre-fix (++x) operator is rather straight forward.
MyClass& operator++()
{
AddOne();
return *this;
}

// the post-fix (x++) is a bit trickier
MyClass operator++(int)
{
MyClass temp(*this);
AddOne();
return temp;
}
}

Note that for the post fix, we've got to make two copies of MyClass (one
in temp, and one for the return), which aren't needed in the pre-fix op++.
Also, note that I could have written the post-fix as:

MyClass operator++(int)
{
MyClass temp(*this);
this->operator++(); // or ++(*this);
return temp;
}

Now, let's write a similar class in C#:

class MyClass
{
public void AddOne() {.....}

public static MyClass operator++(MyClass a)
{
a.AddOne();
return a;
}
}

You'll note that this is the pre-fix operator++. So, where is the
post-fix? The C# compiler creates it for you automatically. And is it
written? Basically:

public static MyClass operator++(MyClass a) // post-fix
{
MyClass b = a.Clone();
++a;
return b;
}

So, like in the C++, the post-fix has to create a copy of the unaltered
object, so that it can be returned.

When an int is used, the operator method is inlined, so, when it's just
"x++;" on a line by itself, the compile can see that the duped value isn't
used, and it can remove the whole creation of it. When ++ is used on some
other type object, the oper++ is done out-of-line, and so, the compiler
cannot remove it.

So, now, let's try your test again, but this using a class:
using System;
public class LikeAnInt
{
int n =0;
public LikeAnInt(int i)
{
n = i;
}
public void AddOne()
{
++n;
}
static public LikeAnInt operator++(LikeAnInt a)
{
a.AddOne();
return a;
}
public int Val
{
get { return n; }
}
}

public class MyClass
{
public static void Main()
{
DateTime d;
TimeSpan t;
int iMax = 1000000000;
int j;
// Test 1 : i++
j = 0;
d = DateTime.Now;
for (LikeAnInt i = new LikeAnInt(0); i.Val < iMax; i++)
j += i.Val;
t = DateTime.Now - d;
Console.WriteLine("i++ : {0}", t.TotalMilliseconds.ToString());

// Test 2 : ++i
j = 0;
d = DateTime.Now;
for (LikeAnInt i = new LikeAnInt(0); i.Val < iMax; ++i)
j += i.Val;
t = DateTime.Now - d;
Console.WriteLine("++i : {0}", t.TotalMilliseconds.ToString());
// Test 3 : i.AddOne()
j = 0;
d = DateTime.Now;
for (LikeAnInt i = new LikeAnInt(0); i.Val < iMax; i.AddOne())
j += i.Val;
t = DateTime.Now - d;
Console.WriteLine("i.AddOne : {0}", t.TotalMilliseconds.ToString());
Console.Read();
}
}

The Results:
SnippetCompiler:
i++ : 44206.6704
++i : 42848.6265
Approx 3% faster

VC#-Debug:
i++ : 34887.6795
++i : 34731.5825
Approx 0.3% faster

VC#-Release:
i++ : 1623.4088
++i : 1607.7991
i.AddOne : 1607.7991
Approx 0.9% faster

A minmal difference, but it's beyond the "noise" level.
--
--
Truth,
James Curran
[erstwhile VC++ MVP]

Home: www.noveltheory.com Work: www.njtheater.com
Blog: www.honestillusion.com Day Job: www.partsearch.com

"Ennixo" <en****@free.fr> wrote in message
news:42***********************@news.free.fr...
Helge Jensen a écrit :
I can't imagine that there is *any* difference whatsoever for the
performance using ++i or i++ (esp. on integral types), and will continue
to think that untill I see a test-program proving otherwise.


so try this sample code (paste in Main method) and you will think that
++i is really faster than other ways to increment by 1. (note: run in
RELEASE mode)

Nov 17 '05 #17
James Curran wrote:

You'll note that this is the pre-fix operator++. So, where is the
post-fix? The C# compiler creates it for you automatically. And is it
written? Basically:

public static MyClass operator++(MyClass a) // post-fix
{
MyClass b = a.Clone();
++a;
return b;
}
No, From the help-files:

The run-time processing of a postfix increment or decrement operation of
the form x++ or x-- consists of the following steps:

If x is classified as a variable:
x is evaluated to produce the variable.
The value of x is saved.
The selected operator is invoked with the saved value of x as its argument.
The value returned by the operator is stored in the location given by
the evaluation of x.
The saved value of x becomes the result of the operation.
Which means that the post-operator++ will only work "as expected" if x
is a struct. Try the example program below.
So, like in the C++, the post-fix has to create a copy of the unaltered
object, so that it can be returned.
If the type is a struct, otherwise a *wrong* (or unhelpfull, at least)
post-operator++ is generated. for C# a struct-return is always a
bit-by-bit copy, so no copy-constructor can be run here, the old struct
is simply copied bit-by bit and has the operator++ applied to it.
When an int is used, the operator method is inlined, so, when it's just
"x++;" on a line by itself, the compile can see that the duped value isn't
used, and it can remove the whole creation of it. When ++ is used on some
other type object, the oper++ is done out-of-line, and so, the compiler
cannot remove it.


Have you disassembled the code to verify that the optimizer does this?
(on structs... of course it won't on classes).

===> test program <===
using System;
class C
{
int i;
public static C operator++(C c) { c.i += 1; return c; }
public override string ToString() { return i.ToString(); }
}
struct S
{
int i;
public static S operator++(S s) { s.i += 1; return s; }
public override string ToString() { return i.ToString (); }
}
class Test
{
public static void print(string prefix, C c)
{ Console.WriteLine("{0}: {1}, id={2}", prefix, c, c.GetHashCode()); }
public static void print(string prefix, S s)
{ Console.WriteLine("{0}: {1}, id={2}", prefix, s, s.GetHashCode()); }

public static void Main()
{
S s = new S();
print("s", s);
print("++s", ++s);
print("s", s);
print("s++", s++);
print("s", s);

C c = new C();
print("c", c);
print("++c", ++c);
print("c", c);
print("c++", c++);
print("c", c);
}
}
===> output <===
s: 0, id=0
++s: 1, id=1
s: 1, id=1
s++: 1, id=1
s: 2, id=2
c: 0, id=1
++c: 1, id=1
c: 1, id=1
c++: 2, id=1
c: 2, id=1
--
Helge Jensen
mailto:he**********@slog.dk
sip:he**********@slog.dk
-=> Sebastian cover-music: http://ungdomshus.nu <=-
Nov 17 '05 #18
"Helge Jensen" <he**********@slog.dk> wrote in message
news:#h**************@TK2MSFTNGP14.phx.gbl...
but since the dawn of time C-programmers have preferred the (1 character
shorter) "i++" to "i+=1". There have *never* *ever* been *any*
performance-reason for this.


No, actually there was. Remember that the original C compiler was
written for a very small machine -- one which measured memory in KB, not MB
(and probably measure it with only 2 digits or fewer)

Nothing about it the language is superflious. If the syntax was
different, the code produced would be different. The best way to see this
is to consider what you can't do with a particular syntax:

The most basic form is
A = B + C;
This would translate into assembler to basically:

ld temp, B ; load B into temp
add temp, C ; add C to temp;
ld A, temp ; Load temp into A

Since the compiler was very stupid with no optimizations, ANY statement
written in that form would be translated the same way.

But, sometimes, you wanted to write:
A = A + C;
This could be translated the same way, but there's a faster way:
add A, C; ; add C to A
But a different translation required a different syntax, hence:
A +=C;

But, sometimes, you wanted to to write:
A = A + 1;
This could be translated the same way, but there's a faster way:
inc A ; increment A
But a different translation required a different syntax, hence:
A++;
--
Truth,
James Curran
[erstwhile VC++ MVP]

Home: www.noveltheory.com Work: www.njtheater.com
Blog: www.honestillusion.com Day Job: www.partsearch.com

Nov 17 '05 #19
Helge is dead on the money.

Ennixo, if you want faster _and_ more readable code, use i += 1 rather
than preincrement. It says exactly what you want to do, and it's a
statement, not an expression, so there is no confusion about creating
copies of anything. The more you tell the compiler about your precise
intentions, the better code it will generate.

In all of this, though, I wonder why you're even bothering with a
managed language. I would think that you would be much better off doing
the heavy lifting in unmanaged C++...?

Nov 17 '05 #20
James Curran wrote:
but since the dawn of time C-programmers have preferred the (1 character
shorter) "i++" to "i+=1". There have *never* *ever* been *any*
performance-reason for this.

No, actually there was. Remember that the original C compiler was
written for a very small machine -- one which measured memory in KB, not MB
(and probably measure it with only 2 digits or fewer)


Can you point to a C-compiler, even a *really* old one, that does not
optimize "x = x + 1" to some available ASM instruction (if one exists on
that architecture) that increments x?
Nothing about it the language is superflious. If the syntax was
different, the code produced would be different. The best way to see this
is to consider what you can't do with a particular syntax:
Since the compiler was very stupid with no optimizations, ANY statement
written in that form would be translated the same way.


I have never seen any compiler do that. Do you have an example?

[...more examples cutted...]

I have implemented compilers, i know how code generation works. If a
compiler have *any* optimizations at all I would hazard a guess that "x
= x + c" is optimized.

--
Helge Jensen
mailto:he**********@slog.dk
sip:he**********@slog.dk
-=> Sebastian cover-music: http://ungdomshus.nu <=-
Nov 17 '05 #21


Helge Jensen wrote:
No, actually there was. Remember that the original C compiler was
written for a very small machine -- one which measured memory in KB,
not MB
(and probably measure it with only 2 digits or fewer)


After a bit of googling, i found:

http://cm.bell-labs.com/cm/cs/who/dmr/primevalC.html, which lists *the*
first C-compiler created at bell-labs.

Funny to see that old code.

Reading: http://cm.bell-labs.com/cm/cs/who/dm...1120c/efftab.s, it
seems to me that even this compiler have support for:

i += C;

optimizations, although I must admit PDP10 assembler is not really my
strong point :)
--
Helge Jensen
mailto:he**********@slog.dk
sip:he**********@slog.dk
-=> Sebastian cover-music: http://ungdomshus.nu <=-
Nov 17 '05 #22
Ennixo <en****@free.fr> wrote:
I can't imagine that there is *any* difference whatsoever for the
performance using ++i or i++ (esp. on integral types), and will continue
to think that untill I see a test-program proving otherwise.


so try this sample code (paste in Main method) and you will think that
++i is really faster than other ways to increment by 1. (note: run in
RELEASE mode)


No I won't, because I can run ildasm and see that the generated code
for both loops is the same.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 17 '05 #23
Ennixo <en****@free.fr> wrote:
Where did you read that? There shouldn't be any difference from the
generated code performance.


i read it in a source code from csharpfr.com and i saw it in some
sources of codeproject.com


Unfortunately that's the kind of myth which often spreads :(

It's always worth looking a bit deeper than an initial benchmark - try
moving the code around and see what happens, try looking at the
generated IL etc.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 17 '05 #24

"James Curran" <ja*********@mvps.org> wrote in message
news:eE**************@TK2MSFTNGP14.phx.gbl...
Everyone seems to be missing the important point about ++i vs i++
optimization...

Namely it comes in play mostly on user defined types with an overload
operator ++.

You're just not going to see the difference using an int.

To understand this, imagine we have a class (MyClass), which has a
member function (AddOne), and we want to implement op++ and ++op. (For
the
moment, I'm going to do this in C++)

class MyClass
{
public:
void AddOne() {.....}

// The Pre-fix (++x) operator is rather straight forward.
MyClass& operator++()
{
AddOne();
return *this;
}

// the post-fix (x++) is a bit trickier
MyClass operator++(int)
{
MyClass temp(*this);
AddOne();
return temp;
}
}

Note that for the post fix, we've got to make two copies of MyClass
(one
in temp, and one for the return), which aren't needed in the pre-fix op++.
Also, note that I could have written the post-fix as:

MyClass operator++(int)
{
MyClass temp(*this);
this->operator++(); // or ++(*this);
return temp;
}

Now, let's write a similar class in C#:

class MyClass
{
public void AddOne() {.....}

public static MyClass operator++(MyClass a)
{
a.AddOne();
return a;
}
}

You'll note that this is the pre-fix operator++. So, where is the
post-fix? The C# compiler creates it for you automatically. And is it
written? Basically:

public static MyClass operator++(MyClass a) // post-fix
{
MyClass b = a.Clone();
++a;
return b;
}

So, like in the C++, the post-fix has to create a copy of the
unaltered
object, so that it can be returned.

When an int is used, the operator method is inlined, so, when it's just
"x++;" on a line by itself, the compile can see that the duped value isn't
used, and it can remove the whole creation of it. When ++ is used on some
other type object, the oper++ is done out-of-line, and so, the compiler
cannot remove it.

So, now, let's try your test again, but this using a class:
using System;
public class LikeAnInt
{
int n =0;
public LikeAnInt(int i)
{
n = i;
}
public void AddOne()
{
++n;
}
static public LikeAnInt operator++(LikeAnInt a)
{
a.AddOne();
return a;
}
public int Val
{
get { return n; }
}
}

public class MyClass
{
public static void Main()
{
DateTime d;
TimeSpan t;
int iMax = 1000000000;
int j;
// Test 1 : i++
j = 0;
d = DateTime.Now;
for (LikeAnInt i = new LikeAnInt(0); i.Val < iMax; i++)
j += i.Val;
t = DateTime.Now - d;
Console.WriteLine("i++ : {0}", t.TotalMilliseconds.ToString());

// Test 2 : ++i
j = 0;
d = DateTime.Now;
for (LikeAnInt i = new LikeAnInt(0); i.Val < iMax; ++i)
j += i.Val;
t = DateTime.Now - d;
Console.WriteLine("++i : {0}", t.TotalMilliseconds.ToString());
// Test 3 : i.AddOne()
j = 0;
d = DateTime.Now;
for (LikeAnInt i = new LikeAnInt(0); i.Val < iMax; i.AddOne())
j += i.Val;
t = DateTime.Now - d;
Console.WriteLine("i.AddOne : {0}", t.TotalMilliseconds.ToString());
Console.Read();
}
}

The Results:
SnippetCompiler:
i++ : 44206.6704
++i : 42848.6265
Approx 3% faster

VC#-Debug:
i++ : 34887.6795
++i : 34731.5825
Approx 0.3% faster

VC#-Release:
i++ : 1623.4088
++i : 1607.7991
i.AddOne : 1607.7991
Approx 0.9% faster

A minmal difference, but it's beyond the "noise" level.
--
--
Truth,
James Curran
[erstwhile VC++ MVP]

Please stop this nonsense about post/prefix increments.
Looak at the IL and more important look at the machine code generated by the
JIT.

Here is the what the JIT produced in optimized builds:
Post-increment loop
02c70086 b978519700 mov ecx,0x975178
02c7008b e8881f78fd call 003f2018
02c70090 895804 mov [eax+0x4],ebx
02c70093 8bf0 mov esi,eax
02c70095 eb0f jmp 02c700a6
02c70097 8b4604 mov eax,[esi+0x4]
02c7009a 8bd0 mov edx,eax
02c7009c c1fa1f sar edx,0x1f
02c7009f 03d8 add ebx,eax
02c700a1 13fa adc edi,edx
02c700a3 ff4604 inc dword ptr [esi+0x4]
02c700a6 817e0400ca9a3b cmp dword ptr [esi+0x4],0x3b9aca00

pre-increment loop

02c70086 b978519700 mov ecx,0x975178
02c7008b e8881f78fd call 003f2018
02c70090 895804 mov [eax+0x4],ebx
02c70093 8bf0 mov esi,eax
02c70095 eb0f jmp 02c700a6
02c70097 8b4604 mov eax,[esi+0x4]
02c7009a 8bd0 mov edx,eax
02c7009c c1fa1f sar edx,0x1f
02c7009f 03d8 add ebx,eax
02c700a1 13fa adc edi,edx
02c700a3 ff4604 inc dword ptr [esi+0x4]
02c700a6 817e0400ca9a3b cmp dword ptr [esi+0x4],0x3b9aca00

See the same routine gets executed for both loops.

Willy.

Nov 17 '05 #25
it's ok, thank you for this enlightment =)

Jon Skeet [C# MVP] a écrit :
Ennixo <en****@free.fr> wrote:
Where did you read that? There shouldn't be any difference from the
generated code performance.


i read it in a source code from csharpfr.com and i saw it in some
sources of codeproject.com

Unfortunately that's the kind of myth which often spreads :(

It's always worth looking a bit deeper than an initial benchmark - try
moving the code around and see what happens, try looking at the
generated IL etc.

Nov 17 '05 #26
Since the dawn of time, C programmers use i++ only when pre-incremented
value of i is needed. Otherwise they use ++i. This has been my experience
for the past 20 years working in C and C++. There is no point in saving the
pre-incremented value if you don't need it.

In the past the pre-increment and post-increment versions did have a
significant difference in performance even in C, if you want to go back to
the dawn of time. This is well known among older C developers. But they are
semantically different as well, so you may as well use the correct operator
in the correct spot, and lessen confusion.

The pre-increment and post-increment versions were invented for good
reasons.

- Frank

"Helge Jensen" <he**********@slog.dk> wrote in message
news:%2****************@TK2MSFTNGP14.phx.gbl...
but since the dawn of time C-programmers have preferred the (1 character
shorter) "i++" to "i+=1". There have *never* *ever* been *any*
performance-reason for this.

I C++ you have overloadable operator++, and this means that you *can*
construct classes where the left++ is cheaper than the right++, therefore
you see C++ programmers do:

for ( IT it = begin; it != end; ++it )

which *may* yield better performance in *rare* cases (the optimizer solves
most simple cases).

Nov 17 '05 #27
> The pre-increment and post-increment versions were invented for good
reasons.

Umm... because the PDP-11 happened to have those two modes? :)

Nov 17 '05 #28
Frank Hileman <fr******@no.spamming.prodigesoftware.com> wrote:
Since the dawn of time, C programmers use i++ only when pre-incremented
value of i is needed. Otherwise they use ++i. This has been my experience
for the past 20 years working in C and C++. There is no point in saving the
pre-incremented value if you don't need it.
Whereas in for loops, I've almost always seen it as i++, just because
it shows you what you're dealing with before what you're going to do
with it, even though you don't care about the pre-incremented value.

I've also almost always seen it as i++ on lines on its own - ++i is
very rare in the code I've seen...
In the past the pre-increment and post-increment versions did have a
significant difference in performance even in C, if you want to go back to
the dawn of time. This is well known among older C developers. But they are
semantically different as well, so you may as well use the correct operator
in the correct spot, and lessen confusion.


I very rarely use either in the case where it makes any difference - it
takes longer reading the code that way than separating the lines,
usually.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 17 '05 #29
++i or i++ can go in any expression, not just a for loop, and they mean
something completely different. So there is a good reason for having both
versions. At the end of the for clause, either one works, but it looks
strange to use i++ when you don't need it. It does not help a novice
understand the operator either.

- Frank

"Helge Jensen" <he**********@slog.dk> wrote in message
news:%2****************@TK2MSFTNGP14.phx.gbl...
No, "++i" and "i++" are *both* expressions. "i = i + 1" and "i += 1", are
statements. Using "++i" as a statement is equivalent to "i = i + 1", or "i
+= 1".

Remember that the syntax of "for" is

'for' '(' STMT ';' EXPR ';' STMT ')' BLOCK_OR_STMT

not:

'for' '(' STMT ';' EXPR ';' EXPR ')' BLOCK_OR_STMT

So we should really be writing:

for ( int i = 0; i < limit; i += 1 )

otherwise you are discard the value of an expression.

but since the dawn of time C-programmers have preferred the (1 character
shorter) "i++" to "i+=1". There have *never* *ever* been *any*
performance-reason for this.

I C++ you have overloadable operator++, and this means that you *can*
construct classes where the left++ is cheaper than the right++, therefore
you see C++ programmers do:

for ( IT it = begin; it != end; ++it )

which *may* yield better performance in *rare* cases (the optimizer solves
most simple cases).
using i++ where you don't need it, you are making code less readable. It
is good practice to use ++ correctly.


Which is not really much except in indexing in loops:

public void CopyTo(Array a, int index)
{ foreach ( object o in this ) a.SetValue(o, index++); }

that i prefer to:

public void CopyTo(Array a, int index)
{
foreach ( object o in this )
{
a.SetValue(o, index);
index += 1;
}
}
--
Helge Jensen
mailto:he**********@slog.dk
sip:he**********@slog.dk
-=> Sebastian cover-music: http://ungdomshus.nu <=-

Nov 17 '05 #30
Frank Hileman <fr******@no.spamming.prodigesoftware.com> wrote:
++i or i++ can go in any expression, not just a for loop, and they mean
something completely different. So there is a good reason for having both
versions. At the end of the for clause, either one works, but it looks
strange to use i++ when you don't need it. It does not help a novice
understand the operator either.


As I said, i++ may look strange to you, but ++i looks strange to me. I
just find i++ more immediately readable.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 17 '05 #31


Bruce Wood wrote:
The pre-increment and post-increment versions were invented for good


reasons.


post increment is certainly are very handy when using pointers as iterators.

I have very rarely had to use pre-increment, mostly those places are
better written with the increment as a statement.

Funnily, IEnumerator is quite close to being used as "i++" when you do:

foreach ( object o in enumerable )

My favorite example of that is:

void CopyTo(Array a, int index) {
foreach ( object o in this )
a.SetValue(o, index++);
}

..... which is almost....

void memcpy(const void *src, void* dst, int length) {
for( const void* o = src; o < src+lengh; ++src )
*(dst++) = o;
}

--
Helge Jensen
mailto:he**********@slog.dk
sip:he**********@slog.dk
-=> Sebastian cover-music: http://ungdomshus.nu <=-
Nov 17 '05 #32
"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
Frank Hileman <fr******@no.spamming.prodigesoftware.com> wrote:
As I said, i++ may look strange to you, but ++i looks strange to me. I
just find i++ more immediately readable.


I agree, I've very rarely seen ++i used in a for loop (or at all for that
matter). Most of the time people just use i++...

--
Adam Clauss
ca*****@tamu.edu
Nov 17 '05 #33
On Wed, 18 May 2005 15:08:53 -0700, "Frank Hileman"
<fr******@no.spamming.prodigesoftware.com> wrote:
++i or i++ can go in any expression, not just a for loop, and they mean
something completely different. So there is a good reason for having both
versions. At the end of the for clause, either one works, but it looks
strange to use i++ when you don't need it. It does not help a novice
understand the operator either.

I have to agree with Jon Skeet here - I have only very rarely seen ++i
used - it's almost always i++. I find ++i much "stranger" than i++.
I've been programming in C since 1974.

And I agree with Jon that when it could be used in some complicated
statement where it actually makes a difference whether it's pre or
post incremented, that I almost always separate it out into a usage of
the variable i and then on another line, I increment the variable.
There is much less confusion about what it means that way, and it
really doesn't cost anything of any significance in terms of
efficiency.

C programmers frequently have a tendency to write inscrutable lines of
code, pleasing themselves with the amount of functionality that they
can pack into that one line of code. Like:

x += ar(**i++);

(the old joke about C programmers is that they claim that they can
write a whole operating system in one line of code)

But the result is an unreadable and error-prone program. As an actual
working programmer for 30 years, I have found that it is far more
important in the real world to write code that can be maintained by
the next programmer that it is to be clever and shave 4 machine cycles
off the pocessing.

My mantra: "always write your programs as if the next programmer to
maintain that code will be a 350-lb homicidal psychopath with a
chainsaw and your home address."

Nov 17 '05 #34
Man, it's nice to hear someone else say that.

Well, all except for the last part. :)

Nov 17 '05 #35

"goody8" <go****@goody8.com> wrote in message
news:ab********************************@4ax.com...
On Wed, 18 May 2005 15:08:53 -0700, "Frank Hileman"
<fr******@no.spamming.prodigesoftware.com> wrote:
++i or i++ can go in any expression, not just a for loop, and they mean
something completely different. So there is a good reason for having both
versions. At the end of the for clause, either one works, but it looks
strange to use i++ when you don't need it. It does not help a novice
understand the operator either.

I have to agree with Jon Skeet here - I have only very rarely seen ++i
used - it's almost always i++. I find ++i much "stranger" than i++.
I've been programming in C since 1974.

And I agree with Jon that when it could be used in some complicated
statement where it actually makes a difference whether it's pre or
post incremented, that I almost always separate it out into a usage of
the variable i and then on another line, I increment the variable.
There is much less confusion about what it means that way, and it
really doesn't cost anything of any significance in terms of
efficiency.

C programmers frequently have a tendency to write inscrutable lines of
code, pleasing themselves with the amount of functionality that they
can pack into that one line of code. Like:

x += ar(**i++);

(the old joke about C programmers is that they claim that they can
write a whole operating system in one line of code)

But the result is an unreadable and error-prone program. As an actual
working programmer for 30 years, I have found that it is far more
important in the real world to write code that can be maintained by
the next programmer that it is to be clever and shave 4 machine cycles
off the pocessing.

My mantra: "always write your programs as if the next programmer to
maintain that code will be a 350-lb homicidal psychopath with a
chainsaw and your home address."


Well, there is a big difference between 1974 C and today's C++.
While it was common sense to use i++ in C, in C++ it's preferable to use ++i
when you don't need the original value, the reason for this is that it is
slightly more efficient to use the pre-increment operator in C++ like James
Curran explained a few messages ago.

Willy.

Nov 17 '05 #36

"goody8" <go****@goody8.com> wrote in message
news:ab********************************@4ax.com...
On Wed, 18 May 2005 15:08:53 -0700, "Frank Hileman"
<fr******@no.spamming.prodigesoftware.com> wrote:
++i or i++ can go in any expression, not just a for loop, and they mean
something completely different. So there is a good reason for having both
versions. At the end of the for clause, either one works, but it looks
strange to use i++ when you don't need it. It does not help a novice
understand the operator either.

I have to agree with Jon Skeet here - I have only very rarely seen ++i
used - it's almost always i++. I find ++i much "stranger" than i++.
I've been programming in C since 1974.

And I agree with Jon that when it could be used in some complicated
statement where it actually makes a difference whether it's pre or
post incremented, that I almost always separate it out into a usage of
the variable i and then on another line, I increment the variable.
There is much less confusion about what it means that way, and it
really doesn't cost anything of any significance in terms of
efficiency.

C programmers frequently have a tendency to write inscrutable lines of
code, pleasing themselves with the amount of functionality that they
can pack into that one line of code. Like:

x += ar(**i++);

(the old joke about C programmers is that they claim that they can
write a whole operating system in one line of code)

But the result is an unreadable and error-prone program. As an actual
working programmer for 30 years, I have found that it is far more
important in the real world to write code that can be maintained by
the next programmer that it is to be clever and shave 4 machine cycles
off the pocessing.

My mantra: "always write your programs as if the next programmer to
maintain that code will be a 350-lb homicidal psychopath with a
chainsaw and your home address."


Well, there is a big difference between 1974 C and today's C++.
While it was common sense to use i++ in C, in C++ it's preferable to use ++i
when you don't need the original value, the reason for this is that it is
slightly more efficient to use the pre-increment operator in C++ like James
Curran explained a few messages ago.

Willy.

Nov 17 '05 #37
On Thu, 19 May 2005 23:46:02 +0200, "Willy Denoyette [MVP]"
<wi*************@telenet.be> wrote:

"goody8" <go****@goody8.com> wrote in message
news:ab********************************@4ax.com.. .
On Wed, 18 May 2005 15:08:53 -0700, "Frank Hileman"
<fr******@no.spamming.prodigesoftware.com> wrote:
++i or i++ can go in any expression, not just a for loop, and they mean
something completely different. So there is a good reason for having both
versions. At the end of the for clause, either one works, but it looks
strange to use i++ when you don't need it. It does not help a novice
understand the operator either.

I have to agree with Jon Skeet here - I have only very rarely seen ++i
used - it's almost always i++. I find ++i much "stranger" than i++.
I've been programming in C since 1974.

And I agree with Jon that when it could be used in some complicated
statement where it actually makes a difference whether it's pre or
post incremented, that I almost always separate it out into a usage of
the variable i and then on another line, I increment the variable.
There is much less confusion about what it means that way, and it
really doesn't cost anything of any significance in terms of
efficiency.

C programmers frequently have a tendency to write inscrutable lines of
code, pleasing themselves with the amount of functionality that they
can pack into that one line of code. Like:

x += ar(**i++);

(the old joke about C programmers is that they claim that they can
write a whole operating system in one line of code)

But the result is an unreadable and error-prone program. As an actual
working programmer for 30 years, I have found that it is far more
important in the real world to write code that can be maintained by
the next programmer that it is to be clever and shave 4 machine cycles
off the pocessing.

My mantra: "always write your programs as if the next programmer to
maintain that code will be a 350-lb homicidal psychopath with a
chainsaw and your home address."


Well, there is a big difference between 1974 C and today's C++.


Is there really? My, my! And here I am still using my PDP11 C
compiler these days.... Wow... I guess you really CAN learn
something new on usenet.

BTW - I have been programming professionally in C++ since 1990, in
Borland, MS and Mac. I've taught classes in C++. These days I'm
mostly using C#.

While it was common sense to use i++ in C, in C++ it's preferable to use ++i
when you don't need the original value, the reason for this is that it is
slightly more efficient to use the pre-increment operator in C++ like James
Curran explained a few messages ago.


Nonsense. There is no real difference between C and C++ with regard
to the auto-incrementing. And either will work just fine, it's merely
a matter of personal preference. Even if I were to believe that there
is a difference between them (and I don't - see Helge Jensen's
comparisons in this thread of the machine language produce for each of
the cases, and others' benchmarks). But that's all compiler-dependent
anyway - some might very well be "slightly more efficient". But
unless you're doing it 10 million times in a tight loop, it's not
going to make any difference at all in your program.

And anyway, as I said, in my 30 years of professional programming, I
really don't recall anyone using pre-increment when post-increment
would also work. It just seems more natural to me to write i++ than
++i.
But, as a friend once remarked, "If it doesn't matter, it doesn't
matter." And my corollary to that Law of Nature is, "if it takes and
oscilloscope to tell the difference, it doesn't matter."


Nov 17 '05 #38
When you implement the operator yourself, the difference is obvious. See
Stroustroup, The C++ Programming Language, section 19.3, for an example of
implementing a postfix increment operator on a user-defined type.

Checked_iter operator++(int) // postfix ++
{
Checked_iter tmp = *this;
++*this; // checked by prefix ++
return tmp;
}

A copy of the original must be made, the increment performed, and the copy
returned. Depending on the meaning of "copy" (how big your user defined type
is, how copy is implemented, etc), and whether the temporary is later
needed, the temporary may be optimized away by your C++ compiler.

In C# the operator is implemented the same way. You do not get to
distinguish between the prefix and postfix operators when implementing your
own user-defined type. You can only implement the prefix version. The
postfix version is implemented by the compiler, and the copy is made for you
automatically. Currently the CLR does not optimize away temporaries produced
in structure operator overloads. C# does seem to perform the optimization
for primitives when the operator is used in a statement. It can never be
optimized away in an expression, as that would change the meaning.

In the same book, there is some discussion about why people hate or love the
operators, and the concise code produced using them (section 6.2.5).

New developers should be aware of the difference between the prefix and
postfix operators, even if others have ignored the difference for years.
Once you are aware of the difference, the postfix version seems the odd one.
"goody8" <go****@goody8.com> wrote in message
news:gb********************************@4ax.com...
Nonsense. There is no real difference between C and C++ with regard
to the auto-incrementing. And either will work just fine, it's merely
a matter of personal preference. Even if I were to believe that there
is a difference between them (and I don't - see Helge Jensen's
comparisons in this thread of the machine language produce for each of
the cases, and others' benchmarks). But that's all compiler-dependent
anyway - some might very well be "slightly more efficient". But
unless you're doing it 10 million times in a tight loop, it's not
going to make any difference at all in your program.

And anyway, as I said, in my 30 years of professional programming, I
really don't recall anyone using pre-increment when post-increment
would also work. It just seems more natural to me to write i++ than
++i.

Nov 17 '05 #39

"goody8" <go****@goody8.com> wrote in message
news:gb********************************@4ax.com...
On Thu, 19 May 2005 23:46:02 +0200, "Willy Denoyette [MVP]"
<wi*************@telenet.be> wrote:

"goody8" <go****@goody8.com> wrote in message
news:ab********************************@4ax.com. ..
On Wed, 18 May 2005 15:08:53 -0700, "Frank Hileman"
<fr******@no.spamming.prodigesoftware.com> wrote:

++i or i++ can go in any expression, not just a for loop, and they mean
something completely different. So there is a good reason for having
both
versions. At the end of the for clause, either one works, but it looks
strange to use i++ when you don't need it. It does not help a novice
understand the operator either.
I have to agree with Jon Skeet here - I have only very rarely seen ++i
used - it's almost always i++. I find ++i much "stranger" than i++.
I've been programming in C since 1974.

And I agree with Jon that when it could be used in some complicated
statement where it actually makes a difference whether it's pre or
post incremented, that I almost always separate it out into a usage of
the variable i and then on another line, I increment the variable.
There is much less confusion about what it means that way, and it
really doesn't cost anything of any significance in terms of
efficiency.

C programmers frequently have a tendency to write inscrutable lines of
code, pleasing themselves with the amount of functionality that they
can pack into that one line of code. Like:

x += ar(**i++);

(the old joke about C programmers is that they claim that they can
write a whole operating system in one line of code)

But the result is an unreadable and error-prone program. As an actual
working programmer for 30 years, I have found that it is far more
important in the real world to write code that can be maintained by
the next programmer that it is to be clever and shave 4 machine cycles
off the pocessing.

My mantra: "always write your programs as if the next programmer to
maintain that code will be a 350-lb homicidal psychopath with a
chainsaw and your home address."

Well, there is a big difference between 1974 C and today's C++.


Is there really? My, my! And here I am still using my PDP11 C
compiler these days.... Wow... I guess you really CAN learn
something new on usenet.

BTW - I have been programming professionally in C++ since 1990, in
Borland, MS and Mac. I've taught classes in C++. These days I'm
mostly using C#.


Impressive but so what?, I'm a professional programmer since 1969 (yes I'm
that old) in BCPL later in B followed by C in 1974 and since 1990 in C++
(with a few years of Assembly in between), I've built system level
components for (and at) DEC's PDP11, Ultrix, VAX VMS, Alpha Open VMS and
OSF later True UNIX 64 and Windows NT on Alpha, I wrote some of the HAL code
and drivers for NT Alpha was a developer on the Clusters for NT on alpha
(taken over by MSFT to build Windows Cluster Server) was member of the
porting group since the early beginning of NT (1990/1) [written for a large
part using C++, was completely rewritten in C ; you want to know why? - on
MIPS later on ALPHA system], until the port of Windows2000 for alpha (whe
even had a 64 bit version of W2K for Alpha never released you probably know
why). Still mostly using C/C++ as system language but also using C# for
general purpose.
What does this prove, guess nothing...
While it was common sense to use i++ in C, in C++ it's preferable to use
++i
when you don't need the original value, the reason for this is that it is
slightly more efficient to use the pre-increment operator in C++ like
James
Curran explained a few messages ago.
Nonsense. There is no real difference between C and C++ with regard
to the auto-incrementing.


*** Sure there is it's small but there is.

And either will work just fine, it's merely a matter of personal preference. Even if I were to believe that there
is a difference between them (and I don't - see Helge Jensen's
comparisons in this thread of the machine language produce for each of
the cases, and others' benchmarks). But that's all compiler-dependent
anyway - some might very well be "slightly more efficient". But
unless you're doing it 10 million times in a tight loop, it's not
going to make any difference at all in your program.

*** Note: The machine language was produced by me, and is the result of
JITed C# code NOT C++, want to see what the C++ compiler generates? You
would be suprised.

And anyway, as I said, in my 30 years of professional programming, I
really don't recall anyone using pre-increment when post-increment
would also work. It just seems more natural to me to write i++ than
++i.


*** So does it to me, but as a said the new 'C++ design guides" do prefer
the pre-increment form ....

You don't have to believe me, look what experts have to say about this:

1. Herb Sutter.
Exceptional C++.
C++ In-Depth Series. Addison Wesley, 2000.
and
C++ Coding Standards

Page 50 Item 28. Prefer calling prefix forms.

2. Meyers' Effective C++ and More Effective C++

3. http://givemefish.com/C++FAQ.pdf
1.4 What is the difference between++var and var++?

4.

http://www.artlogic.com/careers/styleguide.html

snip from :Large-scale Statements:

Note that we prefer to use the pre-increment ++i as a general habit. It is
guaranteed in all languages that use this construct to work identically to
the more commonly seen post-increment i++ that dates back to the earliest
days of the C language. In C++, however, maintaining this habit prevents
possible inefficiencies when looping over an object that exposes an
iteratable interface. Consider the likely cost difference between:
typedef std::vector MyVector;
MyVector vec;
// assume the vector gets filled here....
for (MyVector::const_iterator i = vec.begin(); i != vec.end(); i++)
{
// clever and important code here...
}
and:

for (MyVector::const_iterator i = vec.begin(); i != vec.end(); ++i)
{
// even more clever and important code here...
}
5.

http://www.robthebloke.org/cppdir/St...ateLibrary.htm

6.

http://www.accu.org/bookreviews/publ.../d/d002169.htm

<snip

Unncessary use of post-increment:
It is now well known that for iteration pre-increment usually provides
better performance than post-increment. Still, the book uses post-increment
throughout all the examples, thereby creating and destroying an unnecessary
temporary. A good compiler may be able to optimise away that temporary,
still it is not good nor common practice. In fact, in other places avoiding
temporaries is explicitly a concern (Section 7.4.1, for example).

/snip>

And there's probably a lot more..

Willy.


Nov 17 '05 #40
On Fri, 20 May 2005 17:07:02 +0200, "Willy Denoyette [MVP]"
<wi*************@telenet.be> wrote:

"goody8" <go****@goody8.com> wrote in message
news:gb********************************@4ax.com.. .
On Thu, 19 May 2005 23:46:02 +0200, "Willy Denoyette [MVP]"
<wi*************@telenet.be> wrote:

"goody8" <go****@goody8.com> wrote in message
news:ab********************************@4ax.com ...
On Wed, 18 May 2005 15:08:53 -0700, "Frank Hileman"
<fr******@no.spamming.prodigesoftware.com> wrote:

>++i or i++ can go in any expression, not just a for loop, and they mean
>something completely different. So there is a good reason for having
>both
>versions. At the end of the for clause, either one works, but it looks
>strange to use i++ when you don't need it. It does not help a novice
>understand the operator either.
I have to agree with Jon Skeet here - I have only very rarely seen ++i
used - it's almost always i++. I find ++i much "stranger" than i++.
I've been programming in C since 1974.

And I agree with Jon that when it could be used in some complicated
statement where it actually makes a difference whether it's pre or
post incremented, that I almost always separate it out into a usage of
the variable i and then on another line, I increment the variable.
There is much less confusion about what it means that way, and it
really doesn't cost anything of any significance in terms of
efficiency.

C programmers frequently have a tendency to write inscrutable lines of
code, pleasing themselves with the amount of functionality that they
can pack into that one line of code. Like:

x += ar(**i++);

(the old joke about C programmers is that they claim that they can
write a whole operating system in one line of code)

But the result is an unreadable and error-prone program. As an actual
working programmer for 30 years, I have found that it is far more
important in the real world to write code that can be maintained by
the next programmer that it is to be clever and shave 4 machine cycles
off the pocessing.

My mantra: "always write your programs as if the next programmer to
maintain that code will be a 350-lb homicidal psychopath with a
chainsaw and your home address."


Well, there is a big difference between 1974 C and today's C++.
Is there really? My, my! And here I am still using my PDP11 C
compiler these days.... Wow... I guess you really CAN learn
something new on usenet.

BTW - I have been programming professionally in C++ since 1990, in
Borland, MS and Mac. I've taught classes in C++. These days I'm
mostly using C#.


Impressive but so what?, I'm a professional programmer since 1969 (yes I'm
that old) in BCPL later in B followed by C in 1974 and since 1990 in C++
(with a few years of Assembly in between), I've built system level
components for (and at) DEC's PDP11, Ultrix, VAX VMS, Alpha Open VMS and
OSF later True UNIX 64 and Windows NT on Alpha, I wrote some of the HAL code
and drivers for NT Alpha was a developer on the Clusters for NT on alpha
(taken over by MSFT to build Windows Cluster Server) was member of the
porting group since the early beginning of NT (1990/1) [written for a large
part using C++, was completely rewritten in C ; you want to know why? - on
MIPS later on ALPHA system], until the port of Windows2000 for alpha (whe
even had a 64 bit version of W2K for Alpha never released you probably know
why). Still mostly using C/C++ as system language but also using C# for
general purpose.
What does this prove, guess nothing...

Yes, of course. I was merely responding to the snide remark about
"Well, there is a big difference between 1974 C and today's C++", as
if I was still using a 1974 C compiler. And also, that remark was
meaningless because there is no difference between the auto-increment
in C and C++ (at least not for integers, which is what we were talking
about - for complex objects and overridden operators, sure there's new
stuff with C++).

While it was common sense to use i++ in C, in C++ it's preferable to use
++i
when you don't need the original value, the reason for this is that it is
slightly more efficient to use the pre-increment operator in C++ like
James
Curran explained a few messages ago.
Nonsense. There is no real difference between C and C++ with regard
to the auto-incrementing.


*** Sure there is it's small but there is.


Like what? (seriously - I'm not trying to be argumentative on that
point - I'd really like to know what the small difference is).


And either will work just fine, it's merely
a matter of personal preference. Even if I were to believe that there
is a difference between them (and I don't - see Helge Jensen's
comparisons in this thread of the machine language produce for each of
the cases, and others' benchmarks). But that's all compiler-dependent
anyway - some might very well be "slightly more efficient". But
unless you're doing it 10 million times in a tight loop, it's not
going to make any difference at all in your program.


*** Note: The machine language was produced by me, and is the result of
JITed C# code NOT C++, want to see what the C++ compiler generates? You
would be suprised.

And anyway, as I said, in my 30 years of professional programming, I
really don't recall anyone using pre-increment when post-increment
would also work. It just seems more natural to me to write i++ than
++i.


*** So does it to me, but as a said the new 'C++ design guides" do prefer
the pre-increment form ....

You don't have to believe me, look what experts have to say about this:

1. Herb Sutter.
Exceptional C++.
C++ In-Depth Series. Addison Wesley, 2000.
and
C++ Coding Standards

Page 50 Item 28. Prefer calling prefix forms.

2. Meyers' Effective C++ and More Effective C++

3. http://givemefish.com/C++FAQ.pdf
1.4 What is the difference between++var and var++?

4.

http://www.artlogic.com/careers/styleguide.html

snip from :Large-scale Statements:

Note that we prefer to use the pre-increment ++i as a general habit. It is
guaranteed in all languages that use this construct to work identically to
the more commonly seen post-increment i++ that dates back to the earliest
days of the C language. In C++, however, maintaining this habit prevents
possible inefficiencies when looping over an object that exposes an
iteratable interface. Consider the likely cost difference between:
typedef std::vector MyVector;
MyVector vec;
// assume the vector gets filled here....
for (MyVector::const_iterator i = vec.begin(); i != vec.end(); i++)
{
// clever and important code here...
}
and:

for (MyVector::const_iterator i = vec.begin(); i != vec.end(); ++i)
{
// even more clever and important code here...
}
5.

http://www.robthebloke.org/cppdir/St...ateLibrary.htm

6.

http://www.accu.org/bookreviews/publ.../d/d002169.htm

<snip

Unncessary use of post-increment:
It is now well known that for iteration pre-increment usually provides
better performance than post-increment. Still, the book uses post-increment
throughout all the examples, thereby creating and destroying an unnecessary
temporary. A good compiler may be able to optimise away that temporary,
still it is not good nor common practice. In fact, in other places avoiding
temporaries is explicitly a concern (Section 7.4.1, for example).

/snip>

And there's probably a lot more..

Willy.


Nov 17 '05 #41

Nonsense. There is no real difference between C and C++ with regard
to the auto-incrementing.


*** Sure there is it's small but there is.

Like what? (seriously - I'm not trying to be argumentative on that
point - I'd really like to know what the small difference is).


For any type T, post and prefix increment must (roughly) the following
definition, exemplified as something rather similar to an iterator here:

struct T {
T(const T& t_): /* copy state */ {}
const T& operator=(const T& other)
{ /* copy state*/ ; return *this; }
void next() { /* move to next position */ }

const T& operator++() { next(); return *this; }
const T operator++(int) { T old(*this); next(); return old; }
}

The difference is

- a copy-construction of T -- T::T(const T&)
- a return-by-value of T -- T::operator=(const T&)

C++ allows the compiler to replace the return-by-value with a
copy-construction into space allocated by the caller, and is also
allowed to remove the double copy-construction resulting after the
previous optimization. This means that in general the effective
difference is:

- copy-construction of T -- T::T(const T&)

If the *definition* of T::T(const T&) is available at the call-site of
T::operator++(int) then *that* is a candidate for futher optimization,
so the difference mostly hinges on:

- the expense of T::T(const T&)
- the compilers ability to do optimizations, especially on T::T(const T&)

Since most iterators are implemented as thin wrappers around pointer
manipulation, and declared inline, using ++i or i++ as statements
doesn't matter to performance at all, even on iterators. So don't expect
the performance of your program to change because you change from i++ to
++i.

That, however, is not really a good reason to just using i++ generally.

If you think "i++" is a more readable *statement* than "++i" -- that's
fine by me, but consider whether

for (IT it = begin; it != end; it++)

is really more readable than

for (IT it = begin; it != end; ++it)

or if it's just that you've always just seen: "i++" and thus like it to
stay that way.

--
Helge Jensen
mailto:he**********@slog.dk
sip:he**********@slog.dk
-=> Sebastian cover-music: http://ungdomshus.nu <=-
Nov 17 '05 #42
> No, "++i" and "i++" are *both* expressions. "i = i + 1" and "i += 1",
are statements. Using "++i" as a statement is equivalent to "i = i + 1",
or "i += 1".

Remember that the syntax of "for" is

'for' '(' STMT ';' EXPR ';' STMT ')' BLOCK_OR_STMT

not:

'for' '(' STMT ';' EXPR ';' EXPR ')' BLOCK_OR_STMT


Since when is i+=1 not an expression???
Nov 17 '05 #43


cody wrote:
Since when is i+=1 not an expression???


My god, it is... the horror!

Never seen "i+=e", used as an expression though.

--
Helge Jensen
mailto:he**********@slog.dk
sip:he**********@slog.dk
-=> Sebastian cover-music: http://ungdomshus.nu <=-
Nov 17 '05 #44
On Tue, 24 May 2005 14:40:10 +0200, Helge Jensen wrote:
cody wrote:
Since when is i+=1 not an expression???


My god, it is... the horror!

Never seen "i+=e", used as an expression though.


Using assignments as expressions isn't the most common language pattern.
The most common use I think is the case where you wan't to break on a
certain value, for example:

while ((line = sr.ReadLine()) != null) { /* process line */ }

I have never seen i+=e either though. Now that I think about it, writing
i+=1 is pretty much the same as writing ++i, except that ++i never requires
paranthesis around it.

--
Marcus Andrén
Nov 17 '05 #45
cody wrote:
No, "++i" and "i++" are *both* expressions. "i = i + 1" and "i += 1",
are statements. Using "++i" as a statement is equivalent to "i = i + 1",
or "i += 1".

Remember that the syntax of "for" is

'for' '(' STMT ';' EXPR ';' STMT ')' BLOCK_OR_STMT

not:

'for' '(' STMT ';' EXPR ';' EXPR ')' BLOCK_OR_STMT

Since when is i+=1 not an expression???


i++ and ++i are marked expressions I think because it would make crappy
C coders feel at home, so they could continue writing awful code like:

foo = arr[i++];

or worse:

foo = arr[++i];

i+=1 is short for an assignment, like foo = arr[i]; is too. You have a
point that it's not consistent with i++ which is the same as i+=1, and
I'm with you on that, but I think you can see this as one of the silly
things of C#, like the 'break;' statement after a case block which is
mandatory though fall-through is not supported (so 'break;' is a
complete useless statement in a case block.)

Frans

--
------------------------------------------------------------------------
Get LLBLGen Pro, productive O/R mapping for .NET: http://www.llblgen.com
My .NET blog: http://weblogs.asp.net/fbouma
Microsoft MVP (C#)
------------------------------------------------------------------------
Nov 17 '05 #46
Well is does have one use

switch(i)
{
case 0:
// Do some stuff
break;

case 1:
case 2:
case 3:
// Do some other stuff
break;
case 4:
break; // this explcitly stops us joining case 5 but states we don;t want to do anything
case 5:
// yet more stuff
break;
default:
// raise error as we should never get here
break;
}

Regards

Richard Blewett - DevelopMentor
http://www.dotnetconsult.co.uk/weblog
http://www.dotnetconsult.co.uk

I'm with you on that, but I think you can see this as one of the silly
things of C#, like the 'break;' statement after a case block which is
mandatory though fall-through is not supported (so 'break;' is a
complete useless statement in a case block.)

Frans

--
------------------------------------------------------------------------
Get LLBLGen Pro, productive O/R mapping for .NET: http://www.llblgen.com
My .NET blog: http://weblogs.asp.net/fbouma
Microsoft MVP (C#)
------------------------------------------------------------------------

[microsoft.public.dotnet.languages.csharp]
Nov 17 '05 #47
Richard Blewett [DevelopMentor] wrote:
Well is does have one use

switch(i)
{
case 0:
// Do some stuff
break;

case 1:
case 2:
case 3:
// Do some other stuff
break;
case 4:
break; // this explcitly stops us joining case 5 but states we don;t want to do anything
case 5:
// yet more stuff
break;
default:
// raise error as we should never get here
break;
}
Ok, in this particular case, it has indeed, though without break, you
could have solved it differently as well. Though the explanation for
'break' from Eric Gunnerson was that it was there to make C++
programmers feel at home (If I recall correctly). :)

But indeed, if you want to solve your switches the way you did, it
indeed has. Though I then wonder, why no case statements with ranges
like in VB?

FB

Regards

Richard Blewett - DevelopMentor
http://www.dotnetconsult.co.uk/weblog
http://www.dotnetconsult.co.uk

I'm with you on that, but I think you can see this as one of the silly
things of C#, like the 'break;' statement after a case block which is
mandatory though fall-through is not supported (so 'break;' is a
complete useless statement in a case block.)

Nov 17 '05 #48
> If your app isn't performing well enough, get a profiler and find out
exactly where the bottleneck is. At that point, and only at that point,
should you be really worried about micro-optimisations.


Haven't you ever noticed C# doing funny things though?

For instance, in profiling that I've done for my components, I've noticed a
*severe* performance hit when I use "this.method()" instead of just
"method()". You wouldn't think it would be significantly slower, but it
really seems to be from my profiling tests.

Another way to make your code faster is to never use foreach loops.

foreach (someObj obj in myArrayList)
obj.method()

can be performed much faster if done as:

for (int cnt = 0; cnt < myArrayList.Length; cnt++)
((someObj) myArrayList[cnt]).method()

I think that's the sort of micro-optimizations he's asking for.

I, too, would be interested in such a list if anyone knows of one.

There's more than one way to do it, but unfortunately, so many of the
possible ways are very bad. I want to know the *right* way to do something,
and I've found very little information on how to do it.

--clint
Nov 17 '05 #49
Clint Herron <Cl*********@discussions.microsoft.com> wrote:
If your app isn't performing well enough, get a profiler and find out
exactly where the bottleneck is. At that point, and only at that point,
should you be really worried about micro-optimisations.
Haven't you ever noticed C# doing funny things though?

For instance, in profiling that I've done for my components, I've noticed a
*severe* performance hit when I use "this.method()" instead of just
"method()". You wouldn't think it would be significantly slower, but it
really seems to be from my profiling tests.


Could you post a short but complete program which demonstrates that?

See http://www.pobox.com/~skeet/csharp/complete.html for details of
what I mean by that.

I wouldn't expect the binaries to be any different at all.
Another way to make your code faster is to never use foreach loops.
Not significantly, IME.
foreach (someObj obj in myArrayList)
obj.method()

can be performed much faster if done as:

for (int cnt = 0; cnt < myArrayList.Length; cnt++)
((someObj) myArrayList[cnt]).method()
What exactly do you mean by "much" faster?
I think that's the sort of micro-optimizations he's asking for.

I, too, would be interested in such a list if anyone knows of one.

There's more than one way to do it, but unfortunately, so many of the
possible ways are very bad. I want to know the *right* way to do something,
and I've found very little information on how to do it.


The right way to do something is the most readable way - look how much
more readable it is to use foreach than to use the for loop. Very, very
few applications have bottlenecks due to this kind of usage rather than
algorithmic or IO-based bottlenecks.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 17 '05 #50

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

8
by: OPQ | last post by:
Hi all, I'd happy to have you share some thougts about ultimate optimisations on those 2 topics: (1)- adding one caractere at the end of a string (may be long) (2)- in a dict mapping a key...
2
by: Simon Elliott | last post by:
What optimisation do compilers typically provide when passing STL containers around? For example, if I do something like this: struct Tbloggs { std::string s1; }; typedef...
16
by: simonwittber | last post by:
Hello People. I've have a very tight inner loop (in a game app, so every millisecond counts) which I have optimised below: def loop(self): self_pool = self.pool self_call_exit_funcs =...
17
by: EC-AKD | last post by:
Hi All, I am new to the concept of optimising codes in C. I was wondering if C level inlining of code is any way comparable to macros. I believe that inlining is equivalent to writing macros....
8
by: Jon Maz | last post by:
Hi, I'm facing a code-optimisation issue on an asp.net/vb.net/SQL Server 2000 project. A web page containing not much more than 3 DropDownLists is taking nigh on 6 seconds to load, because each...
6
by: Lee Harr | last post by:
I have a database where I remove the schema public. When I try to use the createlang script, it fails like this ... >createdb foo CREATE DATABASE >psql foo -c "select version()" version...
1
by: David Welch | last post by:
Hi, I have a bit of code where I am relying on empty base member optimisation. The bit of code is below: template<typename Enum> struct EncodePrefix { template<Enum e> struct Apply
1
by: grid | last post by:
Hi, I was exploring the affect of cache on program performance/optimisation.Is it the compilers responsibility only to consider this kind of optimisation or the programmer can do his bit in this...
2
by: special_dragonfly | last post by:
Hello, I know this might be a little cheeky, and if it is, please say, but I need a little hand optimising some code. For the simple reason that this is 'company' code and I have no idea what I'm...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.