Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
C# version of VFP PEMSTATUS()
Message
De
20/01/2010 04:08:31
 
 
À
20/01/2010 03:30:56
Information générale
Forum:
ASP.NET
Catégorie:
Autre
Versions des environnements
Environment:
C# 2.0
Divers
Thread ID:
01444636
Message ID:
01444894
Vues:
35
>>>My favourite of
>>>
>>>>    protected override void OnTextChanged(EventArgs e)
>>>>    {
>>>>        if (this.Parent is IMyInterface)
>>>>        {
>>>>            ((IMyInterface)this.Parent).MyMethod(true);
>>>>        }
>>>>        base.OnTextChanged(e);
>>>>    }
>>>
>>>
>>>is
>>>
>>>>    protected override void OnTextChanged(EventArgs e)
>>>>    {
>>>          IMyInterface o;
>>>>        if ( ( o = this.Parent as IMyInterface) != null )
>>>>        {
>>>>           o.MyMethod(true);
>>>>        }
>>>>        base.OnTextChanged(e);
>>>>    }
>>>
>>
>>Hmm. I defintely win on readability.
>>You might win on efficiency. Have you compared both in ILDASM ?
>
>
>
>>Hmm. I defintely win on readability.
>Well, I can't argue since you are giving the points
:-}

>
>>You might win on efficiency. Have you compared both in ILDASM ?
>No, I haven't - but I have read about this a long time ago
>
>Rumour has it that AS is faster than IS since it needs only one type conversion lookup instead of two
>
>(1) Safely cast without exceptions http://msdn.microsoft.com/en-us/library/cc488006.aspx
>(2) Is http://msdn.microsoft.com/en-us/library/scekt9xw.aspx
>(3) as http://msdn.microsoft.com/en-us/library/cscsdfbt.aspx
>
>
>So, I did a ildasm test
>
>
>Each one has :
>
>isinst     BaseTest.IMyInterface
>
>
>The IS has an additional cast
>
> IL_001d:  castclass  BaseTest.IMyInterface
>
>
>
>		public static void WithIs()
>		{
>			var o = new Regex("p");
>			if (o is IMyInterface)
>				((IMyInterface)o).MyMethod(false);
>		}
>
>  // Code size       42 (0x2a)
>  .maxstack  2
>  .locals init ([0] class [System]System.Text.RegularExpressions.Regex o,
>           [1] bool CS$4$0000)
>  IL_0000:  nop
>  IL_0001:  ldstr      "p"
>  IL_0006:  newobj     instance void [System]System.Text.RegularExpressions.Regex::.ctor(string)
>  IL_000b:  stloc.0
>  IL_000c:  ldloc.0
>  IL_000d:  isinst     BaseTest.IMyInterface
>  IL_0012:  ldnull
>  IL_0013:  cgt.un
>  IL_0015:  ldc.i4.0
>  IL_0016:  ceq
>  IL_0018:  stloc.1
>  IL_0019:  ldloc.1
>  IL_001a:  brtrue.s   IL_0029
>  IL_001c:  ldloc.0
>  IL_001d:  castclass  BaseTest.IMyInterface
>  IL_0022:  ldc.i4.0
>  IL_0023:  callvirt   instance void BaseTest.IMyInterface::MyMethod(bool)
>  IL_0028:  nop
>  IL_0029:  ret
>} // end of method test2::WithIs
>
>
>
>		public static void WithAs()
>		{
>			var o = new Regex("p");
>			IMyInterface xx;
>
>			if ((xx = o as IMyInterface) != null)
>				xx.MyMethod(false);
>		}
>
>
> // Code size       36 (0x24)
>  .maxstack  2
>  .locals init ([0] class [System]System.Text.RegularExpressions.Regex o,
>           [1] class BaseTest.IMyInterface xx,
>           [2] bool CS$4$0000)
>  IL_0000:  nop
>  IL_0001:  ldstr      "p"
>  IL_0006:  newobj     instance void [System]System.Text.RegularExpressions.Regex::.ctor(string)
>  IL_000b:  stloc.0
>  IL_000c:  ldloc.0
>  IL_000d:  isinst     BaseTest.IMyInterface
>  IL_0012:  dup
>  IL_0013:  stloc.1
>  IL_0014:  ldnull
>  IL_0015:  ceq
>  IL_0017:  stloc.2
>  IL_0018:  ldloc.2
>  IL_0019:  brtrue.s   IL_0023
>  IL_001b:  ldloc.1
>  IL_001c:  ldc.i4.0
>  IL_001d:  callvirt   instance void BaseTest.IMyInterface::MyMethod(bool)
>  IL_0022:  nop
>  IL_0023:  ret
>} // end of method test2::WithAs
>
>
>
>
>
>Finally - I have done some testing
>
>WithLoop() : 00:00:02.52
>WithIs() : 00:00:11.35
>WithAs() : 00:00:07.15
>
>
>Is is roughly 9 secs and as around 5 sec = QED
>
>Program below - I have taken out the method calls to IMyInterface - we're not measuring them
>In the case of IS I have done an explicit cast - otherwise IS would have been faster than AS
>
>
>namespace BaseTest
>{
>
>	public class test11
>	{
>		
>
>		public static void Main(string[] args)
>		{
>
>			var pp = new test2();
>			pp.o = new test2();
>
>			ExecuteTimed.Run(pp.WithLoop, false);
>			ExecuteTimed.Run(pp.WithIs, false);
>			ExecuteTimed.Run(pp.WithAs, true);
>		}
>	}
>	public interface IMyInterface
>	{
>		void MyMethod(bool b);
>	
>	}
>	public class test2 : IMyInterface
>	{
>		const int nTimes = 1000000000;
>		public object o;
>		
>		//_____________________________________________________________________
>		public void MyMethod(bool x)
>		{
>		}
>		//______________________________________________________________________
>		public void WithLoop()
>		{
>
>			for (int i = nTimes; --i != 0; )
>				; 
>		}
>		public void WithIs()
>		{
>			
>			IMyInterface xx ;
>			for( int i = nTimes; --i != 0; )
>				if (o is IMyInterface)
>				{
>					xx = (IMyInterface)o;
>					// xx.MyMethod(false);
>				}
>
>		}
>		//______________________________________________________________________
>		public void WithAs()
>		{
>			IMyInterface xx;
>			
>
>			for (int i = nTimes; --i != 0; )
>				if ((xx = o as IMyInterface) != null)
>					; // xx.MyMethod(false);
>		}
>	}
>	//______________________________________________________________________
>}
>
Interesting. TBH, I too expected the 'as' version to be quicker because of repeated cast in the 'is' version - but a *really* clever optimising compiler might have factored that out?
Anyway, now I'm wondering how the IL offset values relate to execution time - given the total offset for 'is' is 29 and 'as' is 23 this obviously doesn't reflect the true cost when translated to machine code. I wonder how results might vary with different processors ?
Précédent
Suivant
Répondre
Fil
Voir

Click here to load this message in the networking platform