Sto scrivendo un programma intensivo di calcolo con VB.NET 2010 e desidero ottimizzare la velocità. Trovo che gli operatori AndAlso
e OrElse
siano anomali lenti se il risultato dell'operazione è assegnato a una variabile di livello di classe. Ad esempio, mentre le dichiarazioniAndAlso OrElse può essere anomalo lentamente
a = _b AndAlso _c
_a = a
occorrono circa 6 cicli macchina tra loro nel exe compilato, la singola istruzione
_a = _b AndAlso _c
dura circa 80 cicli macchina. Qui _a
, _b
e _c
sono variabili booleane private di Form1
e le istruzioni in questione sono in una procedura di istanza di Form1
, di cui a
è una variabile booleana locale.
Non riesco a trovare il motivo per cui la singola istruzione impiega così tanto tempo. Ho esplorato usando NetReflector fino al livello del codice CIL, che sembra buono:
Instruction Explanation Stack
00: ldarg.0 Push Me (ref to current inst of Form1) Me
01: ldarg.0 Push Me Me, Me
02: ldfld bool Form1::_b Pop Me, read _b and push it _b, Me
07: brfalse.s 11 Pop _b; if false, branch to 11 Me
09: ldarg.0 (_b true) Push Me Me, Me
0a: ldfld bool Form1::_c (_b true) Pop Me, read _c and push it _c, Me
0f: brtrue.s 14 (_b true) Pop _c; if true, branch to 14 Me
11: ldc.i4.0 (_b, _c not both true) Push result 0 result, Me
12: br.s 15 Jump unconditionally to 15 result, Me
-----
14: ldc.i4.1 (_b, _c both true) Push result 1 result, Me
15: stfld bool Form1::_a Pop result and Me; write result to _a (empty)
1a:
Qualcuno può far luce sul motivo per cui la dichiarazione _a = _b AndAlso _c
prende 80 cicli macchina al posto del previsto 5 o giù di lì?
Sto usando Windows XP con .NET 4.0 e Visual Studio Express 2010. Ho misurato i tempi con uno snippet francamente sporco che utilizza fondamentalmente un oggetto Stopwatch per temporizzare un ciclo For-Next con 1000 iterazioni contenenti il codice in questione e confrontarlo con un ciclo For-Next vuoto; include un'istruzione inutile in entrambi i cicli per sprecare alcuni cicli e impedire lo stallo del processore. Grezzo ma abbastanza buono per i miei scopi
Scusate se questo commento sembra a qualcuno, ma se stavo cercando velocità di calcolo e tempo di misurazione in cicli, probabilmente non userei VB.NET o .NET in generale. – TyCobb
forse se pubblichi più del codice, possiamo offrire altri suggerimenti per migliorare l'efficienza. – Jeremy
Hai provato a utilizzare solo AND? Soprattutto perché stai lavorando con la variabile Booleans. –