2015-05-04 13 views
6

Ich bekomme einige verwirrende Stopwatch Ergebnisse in meinem C# -Projekt. Stellen Sie sich folgenden Code vor:Stoppuhr gibt verschiedene Ergebnisse, je nachdem, wo sich Code befindet

static void Main(string[] args) 
{ 
    byte[] myEventArray = GetEventByteArrayFromDatabase(); 
    byte[] myEventItemsArray = GetEventItemByteArrayFromDatabase(); 
    uint numEvents = 1000; 
    uint numEventItems = 1000; 

    Stopwatch sw1 = Stopwatch.StartNew(); 
    TestFunction(ref myEventArray, numEvents, ref myEventItemsArray, numEventItems); 
    sw1.Stop(); 

    float timeTakenInSeconds = (float)sw2.ElapsedTicks/Stopwatch.Frequency; 
    Console.WriteLine("Total time: " + timeTakenInSeconds + " seconds. "); 
} 

static void TestFunction(ref byte[] EventArray, uint numEvents, ref byte[] EventItemArray, uint numEventItems) 
{ 
     Calculator calc = new Calculator(); 
     calc.Test(EventArray, numEvents, EventItemArray, numEventItems); 
} 

Ich laufe das und bekomme eine Zeit von etwa 0,2 Sekunden. Nun ist diese betrachten:

static void Main(string[] args) 
{ 
    byte[] myEventArray = GetEventByteArrayFromDatabase(); 
    byte[] myEventItemsArray = GetEventItemByteArrayFromDatabase(); 
    uint numEvents = 1000; 
    uint numEventItems = 1000; 

    Stopwatch sw1 = Stopwatch.StartNew(); 
    Calculator calc = new Calculator(); 
    calc.Test(myEventArray , numEvents, myEventItemsArray , numEventItems); 
    sw1.Stop(); 

    float timeTakenInSeconds = (float)sw1.ElapsedTicks/Stopwatch.Frequency; 
    Console.WriteLine("Total time: " + timeTakenInSeconds + " seconds. "); 
} 

Ich betreibe das, und ein ähnliches Ergebnis erhalten, wie man erwarten würde. Schließlich check this out:

static void Main(string[] args) 
{ 
    byte[] myEventArray = GetEventByteArrayFromDatabase(); 
    byte[] myEventItemsArray = GetEventItemByteArrayFromDatabase(); 
    uint numEvents = 1000; 
    uint numEventItems = 1000; 

    TestFunction(ref myEventArray, numEvents, ref myEventItemsArray, numEventItems); 
} 

static void TestFunction(ref byte[] EventArray, uint numEvents, ref byte[] EventItemArray, uint numEventItems) 
{ 
    Stopwatch sw1 = Stopwatch.StartNew(); 
    Calculator calc = new Calculator(); 
    calc.Test(EventArray, numEvents, EventItemArray, numEventItems); 
    sw1.Stop(); 

    float timeTakenInSeconds = (float)sw1.ElapsedTicks/Stopwatch.Frequency; 
    Console.WriteLine("Total time: " + timeTakenInSeconds + " seconds. "); 
} 

Als ich laufen, dass, das Timing Ergebnis aus irgendeinem Grund konsequent zehnmal schneller ist. Irgendwelche Ideen, warum das der Fall sein könnte?

Ein bisschen mehr Info: Die Rechnerklasse ist in C++/CLI definiert. Ich benutze es als Wrapper für nativen C++ - Code, der schließlich mit den Byte-Arrays funktioniert. Ich kompiliere auch mit dem "unsicheren" Compiler-Flag. Ich bin mir nicht sicher, ob das irgendwelche Auswirkungen haben könnte. Der gesamte Code wird im Freigabemodus kompiliert.

+2

Führen Sie diesen Code in Debug oder Release? Außerdem sieht es so aus, als würdest du verschiedene Methoden einsetzen. 'TestFunction' nimmt einen' ref' Parameter, während 'Test' nicht gilt. –

+0

Was passiert, wenn Sie beide Stoppuhren aktivieren? (innerhalb von TestFunction() und innerhalb von Main()) – DrKoch

+0

check 'sw1' vs.' sw2' (du hast diese Namen auf unglückliche Weise gemischt) – DrKoch

Antwort

2

Ich habe den Grund dafür gefunden. Dies geschieht, weil im ersten Fall die Erstellung meines Calculator-Objekts im Timing-Ergebnis enthalten war und im dritten Fall nicht.

Wenn ich das richtig verstehe, Stack-Variablen werden nicht tatsächlich in der Zeile erstellt, die Sie "new()" eingeben, verschiebt der Compiler die Speicherzuordnung auf die Methode "Prolog".

Sehen Sie diese Seite: https://msdn.microsoft.com/en-us/library/tawsa7cb.aspx

„Der Prolog speichert Argument Register in ihre Privatadressen, falls erforderlich, schiebt nicht-flüchtigen Register auf dem Stapel, ordnet den festen Teil des Stapels für Einheimische und Provisorien und optional gründet ein Rahmenzeiger. "

Also mein "Fall 1" enthielt das "neue" (weil es im Prolog von TestFunction passiert ist) und "Fall 3" schloss es aus, weil das "neue" schon passiert war.

+0

Interessant. Ich würde denken, dass die tatsächliche Zuteilung hier der größte Leistungshit wäre. – aevitas

+0

Die tatsächliche Zuteilung war der größte Erfolg - es passierte einfach nicht dort, wo ich es dachte. – Japes55

Verwandte Themen