Inhaltsverzeichnis

Benchmark

Diese Funktion misst die Zeit, die die Ausführung einer anderen Funktion benötigt. Hierdurch kann man den eigenen Code, sofern notwendig, effizienter hinsichtlich der Ausführungszeit optimieren. Dies könnte durch luaspezifische Optimierungen, als auch durch die Verwendung anderer (Parameter für) API Funktionen des Spiels geschehen.

Verwendung

Benchmark( Testfunktion );

Die Zeit, die ein einzelner Aufruf der Testfunktion benötigt hat, wird nach der Ausführung angezeigt. Man kann mehrere Benchmark Aufrufe für eine Funktion machen, um die Messschwankungen abschätzen zu können.

Einschränkungen

Wenn ein Benchmark direkt bei Spielstart ausgeführt wird, fallen die Ergebnisse anscheinend zu hoch aus. Daher sollte der erste Benchmark Aufruf erst ungefähr 2 Sekunden nach Kartenstart gemacht werden. Dies kann man einfach mit Verzögerte Aktionen / Delay-Funktionen|Delay() oder einem Job erledigen.

Die Testfunktion darf das Spiel nicht verändern!
Dies bedeutet konkret: Die Testfunktion darf beispielsweise keinen Soldatentrupp aus dem Spiel entfernen. Sie könnte aber ein Gebäude erstellen, wenn dies auch automatisch wieder entfernt wird, also das Spiel nach der Ausführung im gleichen Zustand ist wie vor der Ausführung.

Aktionen, wie beispielsweise der Start eines Briefings, wären fatal, da die Funktion während des Tests sehr oft aufgerufen wird.

Es ist nicht möglich eine Ausführungszeit von 0 Millisekunden zu erreichen, da die Zeit, die ein Teil des Benchmark Codes selber verbraucht, nicht herausgerechnet wird. Die Ergebnisse sind aber trotzdem verleichbar, sofern keine anderen CPU intensiven Programme im Hintergrund laufen.

Da viele Rechner unterschiedlich schnell sind, sind die Ergebnisse von verschiedenen Rechnern allenfalls dazu gut um ihre relative Geschwindigkeit zueinander zu testen. Welche Scriptfunktion schneller ist kann mit je einem Ergebnis von 2 Rechnern somit nicht ermittelt werden. Also sollten alle Tests, deren Ergebnisse verglichen werden sollen, auf dem gleichen Rechner (und möglichst im selben Aufruf) ausgeführt werden.

Beispiele

function Slow()
    local t = {};
    for i = 1, 1000 do
        table.insert( t, i );
    end 
end 
 
function Fast()
    local t = {};
    for i = 1, 1000 do
        t[i] = i;
    end 
end 
 
function VeryFast()
end
 
 
Benchmark( Slow );
Benchmark( Fast );
Benchmark( VeryFast );

Benötigter Code

Dieser Code muss ins Script eingefügt werden, damit der Benchmark Aufruf funktioniert:

function Benchmark( _f )
    local total, single;
    for i = 0, 24 do
        total, single = BenchmarkInt( _f, i );
        if total > 0.5 then
            break;
        end
    end
 
    Message( string.format( "Benchmark: %f ms per call.", single * 1000 ) );
end
 
function BenchmarkInt( _f, _exp )
    assert( type( _f ) == "function" );
    assert( type( _exp ) == "number" );
    assert( _exp >= 0 );
    assert( _exp <= 24 );
 
    local loops = 2^_exp;
    local start = XGUIEng.GetSystemTime();
    for i = 1, loops do
        _f();
    end
    local needed = XGUIEng.GetSystemTime() - start;
 
    return needed, needed / loops;
end