Всем привет, подскажите/расскажите пожалуйста, что предпочтительней и почему Lua или Jass?

Первая карта (benchmark.w3m) содержит исходники скрипта.
Вторая карта (benchmark-packed.w3m) уже укомплектована DLL с нативками и готова к запуску.
Решил у себя проверить, вот разница от local integer p и local integer dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
Разница в 24нс на 1 итерацию.
Дальше по поводу вызова функций, ForForce добавляет свою задержку, но хз по идее она не должна сильно повлиять, а по поводу сортировки, тут уже отсутствие оптимизации компилятора/интерпретатора, который есть даже на паскале, по этим нюансам офк джасс уступает, но я говорил непосредственно про нативки и про +- дефолтную "конвенцию" и работу со скриптами от большинства картоделов, кому эта разница не увидится нигде.
Но если уже судить по всем пунктам и сразу, то конечно же LUA будет лучше по всем параметрам в плане производительности и скорости, но у Джасса своя ниша, и куда более простой "путь" входа, что фактически является его самым большим и возможно единственным плюсом.
Это все очень хорошо, но так и не дали главный ответ - что лучше луа или джасс? Чтобы можно было закрыть этот тред
Ответ был уже дан - LUA профитнее по большим пунктам, если есть хоть чуть-чуть знания/азы программирования. Если же нет, то Джасс будет проще и быстрее освоить, да и в плане Вар 3 - я считаю что он всё-равно удобнее.
Загруженные файлы
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
32
Ярг Восьмой, ну тут самая главная проблема - человек которырый задаёт этот вопрос явно ни-то, ни-сё не освоил, и в реалиях картостроения варкравта - это редко нужно, у жасса есть одно весомое преимущество - оно есть на всех патчах из коробки и достаточно просто в освоении.
Все эти конверторы луа - хороши для изучения и баловства, реальные проекты строить и развивать на них не удобно, решение таких задач где луа хорош в сценариях вара - приходится решать не то чтобы редко, очень редко. Ну скорость самого скрипта мало что значит - ибо вы раньше упретесь в производительность движка, начхать луа,жасс или вы длл суните - все они вызывают одни и те же функции игры, реализованные разработчиками, и сделать быстрее - никак нельзя, в итоге - толку что у вас спаун крипов работает чуть чуть быстрее, при 300+ крипах вы ловите так же 6 кадров.
Для начала пойдет и жасс, потому что пересесть на луа ничего не мешает, сам жасс скрипт ничто иное как максимально упрощенный и урезанный ЛУА со строгой типизацией. Ну а главное научится алгоритмы строить и понимать как и что делается, а не сравнивать красоту синтаксиса и кода.
20
Unryze, какие наносекунды, ты же вроде офигеть какие там тулзы пишешь, ну мог бы сделать бенчмарк хотябы - там только на создание сопрограммы и нового стека и потом их убития уйма времени выделяется, что в лупе аж рендер фризился
про execute
ещё
ещё
Про длину названия это ещё из 2006 xgm.guru/forum/showpost.php?p=190747&postcount=5
И потом вроде были бенчмарки, найти уже не знаю по каким кейвордам
Про глобалки вс локалки и массивы вс примитивы
ещё
ещё
Эти люди - не рандомы, писали тулзы и ловили вызовы через дебаггеры, тоже делали инъекции в исполняемый код. wc3c сдох и в веб архиве найти ничего не смог.
Естественно, ещё много лично с ними общался, щас таких мессенджеров уже нет
Есть контраргументы?
Мой тред про мифа Джасса - это и есть контраргумент, а по поводу функций, они в байткоде выходят в id, я не знаю что они там тестировали - кроме как пустой воздух, я же кидал байткод в моём треде для чего? Для красоты? Все функции переводятся в индексы и вызываются по НИМ, потому ДЛИНА их НАЗВАНИЯ не влияет ровно ни на что, ибо оно "компилится" в байткод ЕДИНОЖДЫ.
Я позже разберу все данные тобою ссылки, видать нужно тотально все эти бредни опровергнуть, а то не угомонитесь. :)

Начнём пожалуй очередной разбор мифов:
xgm.guru/forum/showpost.php?p=422071 (ExecuteFunc - создание потока ресурсоёмкое и прочая бурда).
От части правда, но фишка в том, что ForGroup и ForForce создают потоки тоже, и хоть они и медленнее, разница не прямо занебесная. Но так как речь об ExecuteFunc, разберём его подробнее.
Кратко о коде, название функции кешируется и закидывается в "std::map" (косвенно, ибо в С нет этого понятия, но логика та же), что же делается? Функция обрабатывается как "нативка", в том плане, что индексируется и последующие вызовы идут уже СТРОГО по индексу, делается итерация и по StringHash (внутри игры эта функция работает значительно быстрее джасс обработчика) делается проверка та ли функция. Посмотрим же на задержку:
2 мс - это итерация 10к цикла (но для удобства подсчёта оставим всё как есть), и того 53мс на 10000 вызовов, что равно 53 / 10000 = 0.0053мс или же 5300 наносекунд, для любителей секунд - 5.3e-6 секунд.
Проверим теперь обычный call и посмотрим его байткод:
Фактическая задержка тут вообще 1мс, что конечно же в разы быстрее (а точнее в 50 раз, что в целом и ожидалось), а теперь давайте же увеличим имя функции до максимума и посмотрим уже после этого на байткод:
И так, добавилось 2 мс задержки (что не смертельно), но почему же? Смотрим сюда:
В байткоде идёт 16 - call jass, а индекс 4689, то бишь JASM вызывает по индексу, но почему же добавилась задержка? Да вот дело в банальном обработчке вызовов:
Игра ещё и имя выхватывает и делает стрингхеш (чтобы убедиться, что функция есть и вызов её не повлечёт фиаско).
Но фактически эта разница не колоссальная, ибо SomeFunction - длина 12, а SomeFunctionSomeFunctionSomeFunctionSomeFunctionSomeFunctionSomeFunctionSomeFunctionSomeFunctionSomeFunctionSomeFunction - 120, что изменило результат на жалкие 2 мс, которые вы никак и никаким боком не почувствуете.
По поводу TriggerEvaluate vs TriggerExecute - фактически та же песня:
Рассмотрим причину:
А теперь TriggerEvaluate:
В то время как TriggerExecution так же вызывает нет траффик, чтобы убедиться в валидности и вызывает ивент, TriggerEvaluate не делает ничего схожего, потому конечно он быстрее, но если разница в скорости важнее, чем валидность данных, ну даже не знаю. И да TriggerExecute в начале вызывает TriggerEvaluate и лишь потом завершает свой блок, то бишь она жирнее по своему построению, вопрос только в том к чему этот пример ScorpioT1000.
Видать нужно пояснить "Скорп, разница между этими языками по скорости хоть и значительна, но на фактически даже не на уровне НАНОсекунд, а практически на уровне ПИКОсекунд." подробнее, речь о прямом сравнении обработки JASM машины и то, как делаются вызовы, ExecuteFunc - фактически не имеет аналога на ЛУА, потому сравнение банально неправильное (хотя там ExecuteFunc и не нужен, но в пример привёл ты это, хотя я говорил вообще о других вещах).
xgm.guru/forum/showpost.php?p=425373 -> пояснил выше, опять же не понимаю к чему ты это вкинул ибо эта же задержка будет и на ЛУА, иди и проверь?
xgm.guru/forum/showthread.php?t=18742 -> это вообще уровень бреда, убираются лишний код, что конечно же ускорит работу, мне немного аж стыдно, что ты это в пример привёл.
Jass Mythubusters:
Установка literal (которая занимает пикосекунду?) и setvar (который глобалкой ты хотя бы раз делаешь), но да, эта фантомная разница и выдуманные 6 операций (без каких-либо пруфов) - это конечно же аргумент.
И того, что мы имеем, большинство информации банально неверная, а которая и верная - будет иметь тот же результат и на LUA (если вызвать ExecuteFunc или же TriggerExecute на LUA то бишь, будет такая же задержка, ибо это задержка ВНУТРИИГРОВАЯ - задержка движка).
9
Unryze, ну это ты жёстко по фактам решил пройтись, респект за разбор, как раз повод дополнить свою статейку :D
6
Много интересных постов в теме, но ответа на главный вопрос так и не было. Lua или Jass?
28
BaHeK, так сказали же. Если ты на 1.26, то жасс, если же делаешь на рефе или 1.26 с модом war3-lua, то Lua.
20
Много интересных постов в теме, но ответа на главный вопрос так и не было. Lua или Jass?
В ситуации если доступны оба, но если с программированием ОЧЕНЬ слабо знаком - джасс будет проще для начала, но LUA был и будет перспективнее, ибо не только сможешь пилить карты в варкрафте, но и в будущем скрипты под свои нужды как для других программ, так и в целом выучишь хотя бы полезный ЯП. О чём неоднократно тут уже писали. :D
19
Unryze
Длина переменной не влияет на скорость никак - это очередной тупой миф
Написал для теста код, что упорядочивает массив используя сортировку пузырьком.
функция сортировки
function s__NormalArray_sort takes nothing returns nothing
local boolean swapped
local integer temp
local integer i

	loop
		set swapped = false
		set i = 0

		loop
			exitwhen not (i < JASS_MAX_ARRAY_SIZE-1)

			if items[i] > items[i+1] then
				set temp = items[i]
				set items[i] = items[i+1]
				set items[i+1] = temp
				set swapped = true
			endif

			set i = i + 1
		endloop

		exitwhen not swapped
	endloop
	
endfunction

Результаты теста

Имена переменных Затраченное время
Без изменений 90704 мс (1 минута 30 секунд)
Длина 1 символ 84484 мс (1 минута 24 секунд)
Длина 85 символов 387219 мс (6 минут 27 секунд)
Длина 340 символов 1235703 мс (20 минут 35 секунд)

Исходники JASS скрипта

Caller
library Caller initializer init {

     #include "cj_types_priv.j"

    private force dummy_force

    void CallFunction(code f) {
        ForForce(dummy_force, f)
    }

    private void init() {
        dummy_force = CreateForce()
        ForceAddPlayer(dummy_force, Player(0))
    }

}
Benchmark
native GetTickCount takes nothing returns integer
native SetOperationLimitEnabled takes boolean state returns nothing
native IsOperationLimitEnabled takes nothing returns boolean

library benchmark initializer init uses Caller {

    #include "cj_types_priv.j"

    define ITEMS_COUNT = JASS_MAX_ARRAY_SIZE
    
    define MAKE_SORTABLE_ARRAY(TYPE_NAME, items, swapped, temp, i) = {
        integer items[]
    
        struct TYPE_NAME {
        
            static void fill() {
                for (int i = 0; i < ITEMS_COUNT; i++) {
                    items[i] = ITEMS_COUNT - 1 - i
                }
            }
            
            static void sort() {
                bool swapped
                int temp
                int i;
                
                loop {
                    swapped = false
                    
                    for (i = 0; i < ITEMS_COUNT-1; i++) {
                        if items[i] > items[i+1] {
                            temp = items[i]
                            items[i] = items[i+1]
                            items[i+1] = temp
                            swapped = true
                        }
                    }
                    
                    exitwhen not swapped
                }
                
                BJDebugMsg("Sorting finished.")
            }
            
            static bool check() {
                for (int i = 0; i < ITEMS_COUNT-1; i++) {
                    if items[i] > items[i+1] {
                        return false
                    }
                }
                
                for (int i = 0; i < ITEMS_COUNT; i++) {
                    if items[i] != i {
                        return false
                    }
                }
                
                return true
            }
            
            static void benchmark() {
                fill()
                
                int start_time = GetTickCount()
                
                CallFunction(function thistype.sort)
                
                int end_time = GetTickCount()
                int difference = end_time - start_time
                
                if !check() {
                    BJDebugMsg("Sorting failed.")
                }
                else {
                    BJDebugMsg("Time elapsed: " + I2S(difference) + " ms.")
                }
            }
        }
    }
    
    MAKE_SORTABLE_ARRAY(FastArray, a, b, c, d)
    MAKE_SORTABLE_ARRAY(NormalArray, items, swapped, temp, i)
    MAKE_SORTABLE_ARRAY(SlowArray,aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc,ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd)
    MAKE_SORTABLE_ARRAY(VerySlowArray,aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc,dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd)
    
    void start() {
        bool old_state = IsOperationLimitEnabled()
        SetOperationLimitEnabled(false)
        
        CallFunction(function FastArray.benchmark)
        CallFunction(function NormalArray.benchmark)
        CallFunction(function SlowArray.benchmark)
        CallFunction(function VerySlowArray.benchmark)
        
        SetOperationLimitEnabled(old_state)
    }
    
    void init() {
        trigger t = CreateTrigger()
        TriggerAddAction(t, function start)
        TriggerRegisterPlayerChatEvent(t, Player(0), "-start", true)
    }

}

Другие языки

На Pascal'е сортировка заняла 85 мс, что почти в тысячу раз быстрее.
А при использовании статических массивов время снизилось до 72 мс.
Тот же результат выдала и моя asm реализация независимо от типа массива.
pascal
unit Unit1;

{$mode objfpc}{$H+}

interface

uses
	Windows,
	Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls;

type

	{ TForm1 }

	TForm1 = class(TForm)
		StartButton: TButton;
		Log: TMemo;
		procedure StartButtonClick(Sender: TObject);
	private

	public

	end;

    //{$define STATIC_ARRAY}

const
	TEST_ARRAY_SIZE = 8192;

type
	TIntegerArray = array {$ifdef STATIC_ARRAY}[0..TEST_ARRAY_SIZE-1]{$endif} of Integer;
	TSortFunction = procedure (var Items: TIntegerArray);

var
	Form1: TForm1;

implementation

{$R *.lfm}

procedure FillArray({$ifdef STATIC_ARRAY}out{$endif} Items: TIntegerArray);
var
	i: Integer;
begin
	for i:= 0 to High(Items) do begin
		Items[i]:= High(Items) - i;
	end;
end;

procedure BubbleSort({$ifdef STATIC_ARRAY}var{$endif} Items: TIntegerArray);
var
	i: Integer;
	Temp: Integer;
	Swapped: Boolean;
begin
	repeat
		Swapped:= False;

		for i:= 0 to High(Items) - 1 do begin
			if Items[i] > Items[i+1] then begin
				Temp:= Items[i];
				Items[i]:= Items[i+1];
				Items[i+1]:= Temp;

				Swapped:= True;
			end;
		end;

	until not Swapped;
end;

procedure BubbleSortASM(Items: PInteger; Count: Integer); cdecl;
begin
	asm
		pushad

		mov edx, Items
		mov ebx, Count
		dec ebx

		@repeat:
			mov eax, False

			xor ecx, ecx
			@loop:
				lea ebp, [edx+ecx*4]
				mov esi, [ebp]
				mov edi, [ebp+4]

				cmp esi, edi
				jle @skip
					mov [ebp], edi
					mov [ebp+4], esi
					mov eax, True

				@skip:

				inc ecx
				cmp ecx, ebx
				jl @loop

			test eax, eax
			jnz @repeat

		popad
	end;
end;

function IsArraySorted({$ifdef STATIC_ARRAY}const{$endif} Items: TIntegerArray): Boolean;
var
	i: Integer;
begin
	Result:= True;

	for i:= 0 to High(Items) - 1 do begin
		if Items[i] > Items[i+1] then
			Result:= False;
	end;

	for i:= 0 to High(Items) do begin
		if Items[i] <> i then
			Result:= False;
	end;
end;

procedure StartTest(TestFunction: TSortFunction);
var
	Items: TIntegerArray = nil;
	Frequency: Qword;
	StartTime, EndTime, ElapsedTime: Qword;
begin
	QueryPerformanceFrequency(@Frequency);

	{$ifndef STATIC_ARRAY}SetLength(Items, TEST_ARRAY_SIZE);{$endif}
	FillArray(Items);

	QueryPerformanceCounter(@StartTime);
	TestFunction(Items);
	QueryPerformanceCounter(@EndTime);

	ElapsedTime:= EndTime - StartTime;

	if IsArraySorted(Items) then
		Form1.Log.Lines.Add('Time elapsed: %d ms.', [ElapsedTime div (Frequency div 1000)])
	else
		Form1.Log.Lines.Add('Sorting failed.');
end;

procedure BubbleSortBenchmark(var Items: TIntegerArray);
begin
	BubbleSort(Items);
end;

procedure BubbleSortASMBenchmark(var Items: TIntegerArray);
begin
	BubbleSortASM(@Items[0], Length(Items));
end;

{ TForm1 }

procedure TForm1.StartButtonClick(Sender: TObject);
begin
	StartTest(@BubbleSortBenchmark);
	StartTest(@BubbleSortASMBenchmark);
end;

end.
20
Unryze
Длина переменной не влияет на скорость никак - это очередной тупой миф
Написал для теста код, что упорядочивает массив используя сортировку пузырьком.
функция сортировки
function s__NormalArray_sort takes nothing returns nothing
local boolean swapped
local integer temp
local integer i

	loop
		set swapped = false
		set i = 0

		loop
			exitwhen not (i < JASS_MAX_ARRAY_SIZE-1)

			if items[i] > items[i+1] then
				set temp = items[i]
				set items[i] = items[i+1]
				set items[i+1] = temp
				set swapped = true
			endif

			set i = i + 1
		endloop

		exitwhen not swapped
	endloop
	
endfunction

Результаты теста

Имена переменных Затраченное время
Без изменений 90704 мс (1 минута 30 секунд)
Длина 1 символ 84484 мс (1 минута 24 секунд)
Длина 85 символов 387219 мс (6 минут 27 секунд)
Длина 340 символов 1235703 мс (20 минут 35 секунд)

Исходники JASS скрипта

Caller
library Caller initializer init {

     #include "cj_types_priv.j"

    private force dummy_force

    void CallFunction(code f) {
        ForForce(dummy_force, f)
    }

    private void init() {
        dummy_force = CreateForce()
        ForceAddPlayer(dummy_force, Player(0))
    }

}
Benchmark
native GetTickCount takes nothing returns integer
native SetOperationLimitEnabled takes boolean state returns nothing
native IsOperationLimitEnabled takes nothing returns boolean

library benchmark initializer init uses Caller {

    #include "cj_types_priv.j"

    define ITEMS_COUNT = JASS_MAX_ARRAY_SIZE
    
    define MAKE_SORTABLE_ARRAY(TYPE_NAME, items, swapped, temp, i) = {
        integer items[]
    
        struct TYPE_NAME {
        
            static void fill() {
                for (int i = 0; i < ITEMS_COUNT; i++) {
                    items[i] = ITEMS_COUNT - 1 - i
                }
            }
            
            static void sort() {
                bool swapped
                int temp
                int i;
                
                loop {
                    swapped = false
                    
                    for (i = 0; i < ITEMS_COUNT-1; i++) {
                        if items[i] > items[i+1] {
                            temp = items[i]
                            items[i] = items[i+1]
                            items[i+1] = temp
                            swapped = true
                        }
                    }
                    
                    exitwhen not swapped
                }
                
                BJDebugMsg("Sorting finished.")
            }
            
            static bool check() {
                for (int i = 0; i < ITEMS_COUNT-1; i++) {
                    if items[i] > items[i+1] {
                        return false
                    }
                }
                
                for (int i = 0; i < ITEMS_COUNT; i++) {
                    if items[i] != i {
                        return false
                    }
                }
                
                return true
            }
            
            static void benchmark() {
                fill()
                
                int start_time = GetTickCount()
                
                CallFunction(function thistype.sort)
                
                int end_time = GetTickCount()
                int difference = end_time - start_time
                
                if !check() {
                    BJDebugMsg("Sorting failed.")
                }
                else {
                    BJDebugMsg("Time elapsed: " + I2S(difference) + " ms.")
                }
            }
        }
    }
    
    MAKE_SORTABLE_ARRAY(FastArray, a, b, c, d)
    MAKE_SORTABLE_ARRAY(NormalArray, items, swapped, temp, i)
    MAKE_SORTABLE_ARRAY(SlowArray,aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc,ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd)
    MAKE_SORTABLE_ARRAY(VerySlowArray,aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc,dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd)
    
    void start() {
        bool old_state = IsOperationLimitEnabled()
        SetOperationLimitEnabled(false)
        
        CallFunction(function FastArray.benchmark)
        CallFunction(function NormalArray.benchmark)
        CallFunction(function SlowArray.benchmark)
        CallFunction(function VerySlowArray.benchmark)
        
        SetOperationLimitEnabled(old_state)
    }
    
    void init() {
        trigger t = CreateTrigger()
        TriggerAddAction(t, function start)
        TriggerRegisterPlayerChatEvent(t, Player(0), "-start", true)
    }

}

Другие языки

На Pascal'е сортировка заняла 85 мс, что почти в тысячу раз быстрее.
А при использовании статических массивов время снизилось до 72 мс.
Тот же результат выдала и моя asm реализация независимо от типа массива.
pascal
unit Unit1;

{$mode objfpc}{$H+}

interface

uses
	Windows,
	Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls;

type

	{ TForm1 }

	TForm1 = class(TForm)
		StartButton: TButton;
		Log: TMemo;
		procedure StartButtonClick(Sender: TObject);
	private

	public

	end;

    //{$define STATIC_ARRAY}

const
	TEST_ARRAY_SIZE = 8192;

type
	TIntegerArray = array {$ifdef STATIC_ARRAY}[0..TEST_ARRAY_SIZE-1]{$endif} of Integer;
	TSortFunction = procedure (var Items: TIntegerArray);

var
	Form1: TForm1;

implementation

{$R *.lfm}

procedure FillArray({$ifdef STATIC_ARRAY}out{$endif} Items: TIntegerArray);
var
	i: Integer;
begin
	for i:= 0 to High(Items) do begin
		Items[i]:= High(Items) - i;
	end;
end;

procedure BubbleSort({$ifdef STATIC_ARRAY}var{$endif} Items: TIntegerArray);
var
	i: Integer;
	Temp: Integer;
	Swapped: Boolean;
begin
	repeat
		Swapped:= False;

		for i:= 0 to High(Items) - 1 do begin
			if Items[i] > Items[i+1] then begin
				Temp:= Items[i];
				Items[i]:= Items[i+1];
				Items[i+1]:= Temp;

				Swapped:= True;
			end;
		end;

	until not Swapped;
end;

procedure BubbleSortASM(Items: PInteger; Count: Integer); cdecl;
begin
	asm
		pushad

		mov edx, Items
		mov ebx, Count
		dec ebx

		@repeat:
			mov eax, False

			xor ecx, ecx
			@loop:
				lea ebp, [edx+ecx*4]
				mov esi, [ebp]
				mov edi, [ebp+4]

				cmp esi, edi
				jle @skip
					mov [ebp], edi
					mov [ebp+4], esi
					mov eax, True

				@skip:

				inc ecx
				cmp ecx, ebx
				jl @loop

			test eax, eax
			jnz @repeat

		popad
	end;
end;

function IsArraySorted({$ifdef STATIC_ARRAY}const{$endif} Items: TIntegerArray): Boolean;
var
	i: Integer;
begin
	Result:= True;

	for i:= 0 to High(Items) - 1 do begin
		if Items[i] > Items[i+1] then
			Result:= False;
	end;

	for i:= 0 to High(Items) do begin
		if Items[i] <> i then
			Result:= False;
	end;
end;

procedure StartTest(TestFunction: TSortFunction);
var
	Items: TIntegerArray = nil;
	Frequency: Qword;
	StartTime, EndTime, ElapsedTime: Qword;
begin
	QueryPerformanceFrequency(@Frequency);

	{$ifndef STATIC_ARRAY}SetLength(Items, TEST_ARRAY_SIZE);{$endif}
	FillArray(Items);

	QueryPerformanceCounter(@StartTime);
	TestFunction(Items);
	QueryPerformanceCounter(@EndTime);

	ElapsedTime:= EndTime - StartTime;

	if IsArraySorted(Items) then
		Form1.Log.Lines.Add('Time elapsed: %d ms.', [ElapsedTime div (Frequency div 1000)])
	else
		Form1.Log.Lines.Add('Sorting failed.');
end;

procedure BubbleSortBenchmark(var Items: TIntegerArray);
begin
	BubbleSort(Items);
end;

procedure BubbleSortASMBenchmark(var Items: TIntegerArray);
begin
	BubbleSortASM(@Items[0], Length(Items));
end;

{ TForm1 }

procedure TForm1.StartButtonClick(Sender: TObject);
begin
	StartTest(@BubbleSortBenchmark);
	StartTest(@BubbleSortASMBenchmark);
end;

end.
Про длину я затупил и сам же это и доказал своими тестами, но и тебе спасибо за твой тест. Скинь пожаолуйста карту, чтобы можно было глянуть что cJass в итоге превратит в обычный джасс, хочу посмотреть и замерить тоже, но я выше показал причину дополнения задержки, с переменными похоже та же басня, что странно:
Всё-таки очень странно, что сортировка на столько дикую разницу имеет, имею сомнения как не крути.
Загруженные файлы
25
Такие аргументированные срачи не часто встретишь. Однако именно в таком обсуждении можно найти некую истину для себя и узнать что-то новое. Спасибо ребята :)
37
Это все очень хорошо, но так и не дали главный ответ - что лучше луа или джасс? Чтобы можно было закрыть этот тред
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.