473,804 Members | 2,141 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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
55 3735
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.WriteLi ne("i++ : {0}", t.TotalMillisec onds.ToString() );
// Test 2 : ++i
j = 0;
d = DateTime.Now;
for (int i = 0; i < iMax; ++i)
j += i;
t = DateTime.Now - d;
Console.WriteLi ne("++i : {0}", t.TotalMillisec onds.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.WriteLi ne("i += 1 : {0}", t.TotalMillisec onds.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.WriteLi ne("i = i + 1 : {0}", t.TotalMillisec onds.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**********@s log.dk> wrote in message
news:%2******** ********@TK2MSF TNGP15.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 "optimizati on" 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
performanc e 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++(MyCl ass 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++(MyCl ass 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++(Like AnInt 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.WriteLi ne("i++ : {0}", t.TotalMillisec onds.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.WriteLi ne("++i : {0}", t.TotalMillisec onds.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.WriteLi ne("i.AddOne : {0}", t.TotalMillisec onds.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++(MyCl ass 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.WriteLi ne("{0}: {1}, id={2}", prefix, c, c.GetHashCode() ); }
public static void print(string prefix, S s)
{ Console.WriteLi ne("{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**********@s log.dk> wrote in message
news:#h******** ******@TK2MSFTN GP14.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

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

Similar topics

8
1437
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 to a list of int, remove every entrie where the list of int have of length < 2
2
1882
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 std::vector<Tbloggs> TbloggsList;
16
1495
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 = self.call_exit_funcs self_pool_popleft = self.pool.popleft self_pool_append = self.pool.append
17
2372
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. However I had this strange feeling if I should go for macros wherever necessary instead of inlining the codes. In my project, I have to use basic operations like add and sub many times. So I initially inlined them and found a lot of optimisation.
8
1900
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 ddl opens up a separate connection to the DB, pulls out its data, and closes its own connection before the next ddl repeats the process. The code to handle each DDL's connection to the DB is packaged in an object (presentation-layer code...
6
3612
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 --------------------------------------------------------------------- PostgreSQL 7.4.1 on i386-portbld-freebsd4.9, compiled by GCC 2.95.4 (1 row)
1
2001
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
2066
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 case ? Reading through the "Expert C Programming" text,it mentions how the below program can be efficient taking the cache details into accont. The below program can be executed using the two versions of copy alternatively and running the time...
2
1261
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 allowed to release and not as the case may be I've changed anything that could give an indication of the company - if that makes any sense... for the code below: text_buffer is a single record from an XML stream. I can't read in the entire XML...
0
9714
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
10350
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 tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10351
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
10096
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
9174
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, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
6866
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5673
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
3834
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
3002
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.