Re: C# very optimisation
- From: Helge Jensen <helge.jensen@xxxxxxx>
- Date: Wed, 18 May 2005 19:16:41 +0200
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:helge.jensen@xxxxxxx sip:helge.jensen@xxxxxxx -=> Sebastian cover-music: http://ungdomshus.nu <=- .
- References:
- C# very optimisation
- From: Ennixo
- Re: C# very optimisation
- From: Jon Skeet [C# MVP]
- Re: C# very optimisation
- From: Ennixo
- Re: C# very optimisation
- From: Lebesgue
- Re: C# very optimisation
- From: Ennixo
- Re: C# very optimisation
- From: Søren Reinke
- Re: C# very optimisation
- From: Helge Jensen
- Re: C# very optimisation
- From: Ennixo
- Re: C# very optimisation
- From: James Curran
- C# very optimisation
- Prev by Date: RE: Creaing a control array of Radio Button in web application
- Next by Date: Reusing a local address/port when creating sockets that send data
- Previous by thread: Re: C# very optimisation
- Next by thread: Re: C# very optimisation
- Index(es):