Jass
Стандартный скриптовый (функционально/псевдо-объектно) ориентированный, строго-типизированный язык с автоматическим управлением памятью, для разработки карт в Warcraft 3, имеющий достаточно устаревший синтаксис и минимум современных парадигм.
lua
Процедурный динамически типизированный модульный язык с автоматическим управлением памятью. Язык был интегрирован в до Рефордж версии Ev3nt'ом. Данный язык имеет более современный синтаксис и имеет достаточное количество современных парадигм.
AngelScript
Интерпретируемый строго-типизированный, объекто-ориентированный язык программирования, разработанный специально для использования в качестве скриптового языка в приложениях. Был интегрирован совсем недавно мною (Unryze) с поддержкой пользователя GPSProlapse.
Для чего эта статья?
Очень часто заходят разговоры о скорости того или иного языка, однако все эти "доводы" построены буквально на воздухе, без особых тестов/проверок, что и хотелось уже решить раз и навсегда. Однако, сравнение конечно же синтетическое, и не предназначен для принижения производительности какого-либо из языков. Хочется так же добавить, что как только логика будет отходить от использования нативок игры, то в этих ситуациях lua и AngelScript будут всегда быстрее. А на сколько, это мы узнаем чуть позже. Для начала сделаем сравнение чего-то часто используемого.
Тесты CreateUnit
Jass
function TestFunctionDelayed takes nothing returns nothing
local integer i = 0
call RemoveUnit(CreateUnit(Player(0), 'Hpal', 0., 0., 0.))
loop
exitwhen i > 10
call BenchmarkStart()
call CreateUnit(Player(0), 'Hpal', 0., 0., 0.)
call BenchmarkEnd()
call ConsolePrint("Elapsed: " + BenchmarkGetElapsed(2) + "(ms) | " + BenchmarkGetElapsed(1) + "(us) | " + BenchmarkGetElapsed(0) + "(ns)\n")
call BenchmarkReset()
set i = i + 1
endloop
endfunction
function OnMapInitDelayed takes nothing returns nothing
call TimerStart(GetExpiredTimer(), .5, false, function TestFunctionDelayed)
endfunction
function InitTrig_InitTests takes nothing returns nothing
call TimerStart(CreateTimer(), .01, false, function OnMapInitDelayed)
endfunction
lua
function TestFunctionDelayed( )
RemoveUnit( CreateUnit( Player( 0 ), FourCC( "Hpal" ), 0., 0., 0. ) )
for i = 0, 10, 1
do
BenchmarkStart( )
CreateUnit( Player( 0 ), FourCC( "Hpal" ), 0., 0., 0. )
BenchmarkEnd( )
ConsolePrint( "Elapsed: " .. BenchmarkGetElapsed( 2 ) .. "(ms) | " .. BenchmarkGetElapsed( 1 ) .. "(us) | " .. BenchmarkGetElapsed( 0 ) .. "(ns)" .. "\n" )
BenchmarkReset( )
end
end
function OnMapInitDelayed( )
TimerStart( GetExpiredTimer( ), .5, false, TestFunctionDelayed )
end
function main( )
TimerStart( CreateTimer( ), .01, false, OnMapInitDelayed )
end
main( )
AngelScript
void TestFunctionDelayed( )
{
RemoveUnit( CreateUnit( Player( 0 ), 'Hpal', 0.f, 0.f, 0.f ) );
for ( int i = 0; i < 10; i++ )
{
BenchmarkStart( );
CreateUnit( Player( 0 ), 'Hpal', 0.f, 0.f, 0.f );
BenchmarkEnd( );
ConsolePrint( "Elapsed: " + BenchmarkGetElapsed( 2 ) + "(ms) | " + BenchmarkGetElapsed( 1 ) + "(us) | " + BenchmarkGetElapsed( 0 ) + "(ns)" + "\n" );
BenchmarkReset( );
}
}
void OnMapInitDelayed( )
{
TimerStart( GetExpiredTimer( ), .5f, false, @TestFunctionDelayed );
}
void main( )
{
TimerStart( CreateTimer( ), .01f, false, @OnMapInitDelayed );
}
Результаты CreateUnit
Итого мы получаем, что языки примерно одинаково справились с поставленной задачей. Данное сравнение не конечное и другие сравнения будут добавлены, но для более объективных тестов хотелось бы увидеть примеры от вас - читателей.
Тесты Скорости доступа к переменным
Jass
globals
integer someInt
integer array someIntArray
endglobals
function TestStupidShit takes nothing returns nothing
local integer i = -1
set someInt = 10000
set someIntArray[ 8191 ] = 10000
set uTest = CreateUnit( Player( 0 ), 'htow', -500., -500., .0 )
set iTest = GetHandleId( uTest )
call BenchmarkStart( )
set i = 0
call BenchmarkEnd( )
call ConsolePrint( "Elapsed: " + BenchmarkGetElapsed( 2 ) + "(ms) | " + BenchmarkGetElapsed( 1 ) + "(us) | " + BenchmarkGetElapsed( 0 ) + "(ns)" + "\n" )
call BenchmarkReset( )
call BenchmarkStart( )
set i = someIntArray[ 8191 ]
call BenchmarkEnd( )
call ConsolePrint( "Elapsed: " + BenchmarkGetElapsed( 2 ) + "(ms) | " + BenchmarkGetElapsed( 1 ) + "(us) | " + BenchmarkGetElapsed( 0 ) + "(ns)" + "\n" )
call BenchmarkReset( )
call BenchmarkStart( )
set i = someInt
call BenchmarkEnd( )
call ConsolePrint( "Elapsed: " + BenchmarkGetElapsed( 2 ) + "(ms) | " + BenchmarkGetElapsed( 1 ) + "(us) | " + BenchmarkGetElapsed( 0 ) + "(ns)" + "\n" )
call BenchmarkReset( )
endfunction
lua
someInt = -1;
someIntArray = { };
function TestFunctionDelayed( )
i = -1
someInt = 100000
someIntArray[8191] = 100000
BenchmarkStart( )
i = 0
BenchmarkEnd( )
ConsolePrint( "Elapsed: " .. BenchmarkGetElapsed( 2 ) .. "(ms) | " .. BenchmarkGetElapsed( 1 ) .. "(us) | " .. BenchmarkGetElapsed( 0 ) .. "(ns)" .. "\n" )
BenchmarkReset( )
BenchmarkStart( )
i = someIntArray[ 8191 ]
BenchmarkEnd( )
ConsolePrint( "Elapsed: " .. BenchmarkGetElapsed( 2 ) .. "(ms) | " .. BenchmarkGetElapsed( 1 ) .. "(us) | " .. BenchmarkGetElapsed( 0 ) .. "(ns)" .. "\n" )
BenchmarkReset( )
BenchmarkStart( )
i = someInt
BenchmarkEnd( )
ConsolePrint( "Elapsed: " .. BenchmarkGetElapsed( 2 ) .. "(ms) | " .. BenchmarkGetElapsed( 1 ) .. "(us) | " .. BenchmarkGetElapsed( 0 ) .. "(ns)" .. "\n" )
BenchmarkReset( )
end
AngelScript
int someInt;
array<int> someIntArray(8192);
void TestFunctionDelayed( )
{
int i = -1;
someInt = 100000;
someIntArray[8191] = 100000;
BenchmarkStart( );
i = 0;
BenchmarkEnd( );
ConsolePrint( "Elapsed: " + BenchmarkGetElapsed( 2 ) + "(ms) | " + BenchmarkGetElapsed( 1 ) + "(us) | " + BenchmarkGetElapsed( 0 ) + "(ns)" + "\n" );
BenchmarkReset( );
BenchmarkStart( );
i = someIntArray[ 8191 ];
BenchmarkEnd( );
ConsolePrint( "Elapsed: " + BenchmarkGetElapsed( 2 ) + "(ms) | " + BenchmarkGetElapsed( 1 ) + "(us) | " + BenchmarkGetElapsed( 0 ) + "(ns)" + "\n" );
BenchmarkReset( );
BenchmarkStart( );
i = someInt;
BenchmarkEnd( );
ConsolePrint( "Elapsed: " + BenchmarkGetElapsed( 2 ) + "(ms) | " + BenchmarkGetElapsed( 1 ) + "(us) | " + BenchmarkGetElapsed( 0 ) + "(ns)" + "\n" );
BenchmarkReset( );
}
Результаты Скорости доступа к переменным
По итогу, lua и AngelScript примерно одинаковой скорости и быстрее чем Jass в 2~3 раза. В целом, можно ожидать общий прирост скорости над Jass может дойти до 5. Однако даже учитывая все эти нюансы, проекты, которые бы сильно почувствовали разницу от разницы в наносекундах - очень мало, но да, они есть. Однако чем больше данных будет обрабатываться без вовлечения движка игры, тем обработка будет быстрее. Один из примеров - это энумерация юнитов через массив, а не через Group API.
Edited by ScorpioT1000
Edited by Unryze
Исправлен карта в архиве.