Будет ли сравнение например if var == 0 then выполняться быстрее чем GetHandleId( timer ) ? По идеи же да ?

Вместо того, чтобы гадать, можно провести замеры.
Я делал мод, который добавляет нативки для бенчмарков — просто кинь JassApi.dll и
natives.mix в папку с игрой и объяви в коде нативки:
native GetTickCount takes nothing returns integer
native SetOperationLimitEnabled takes boolean state returns nothing
native IsOperationLimitEnabled takes nothing returns boolean
После чего сделай функцию, которая многократно выполняет интересующее тебя действие и засеки время до и после исполнения, затем вычисли разницу.
Важно сделать так, чтобы функция исполнялась достаточно долго для того, чтобы погрешность была не слишком велика. Измерять одно действие смысла мало, а вот повторить его миллион раз уже может иметь смысл, чтобы на выполнение задачи ушли секунды, а не наносекунды, что может привести к погрешности ±100%.
Не забудь отключить лимит операций с помощью вызова SetOperationLimitEnabled(false), а иначе виртуальная машина убьет поток из-за превышения лимита.
`
ОЖИДАНИЕ РЕКЛАМЫ...
Этот комментарий удален
23
Да, вызов функции ресурсозатратнее, чем обращение к переменной.
П. С. Полезная статья про jass.
15
Да просто есть такая функция:
function MUIHandle takes nothing returns integer 
    return GetHandleId( GetExpiredTimer() )
endfunction
Думаю такой вариант будет лучше:
function MUIHandle takes nothing returns integer 
    if MUIID == 0 then
        set MUIID = GetHandleId( GetExpiredTimer() )
    endif
    return MUIID
endfunction
Т.е. вызов функции GetHandleId происходит в первом вызове функции, а в следующих уже значение возвращает.
Ну и в конце выгрузки всего из хэш таблицы присваивать MUIID 0.
Ответы (4)
23
LastUchiha, не сильно скорость различается тут, считай никак. Всё равно вызовы функции есть. Экономить на наносекундах - такое себе)
30
Экономить на наносекундах - такое себе)
Ты не понимаешь, нужно экономить на наносекундах вызова функции, а потом писать шикарные O(n!) алгоритмы.
30
Думаю такой вариант будет лучше
Если MUIID когда-то примет значение отличное от ноля, то она больше никогда ничего кроме него не вернёт. Гениально.
15
nazarpunk, будет сетаться 0 в конце всех выгрузок из хэша.
Поэтому всё будет нормально работать.
32
Зачем, почему не взять просто GetHandleId от истекшего таймера, и судя по названию муи - то таймеров может быть много, хендл ты вернешь первого сработавшего. Какая то несусветная хрень, напиши сразу че делать собрался, то не понимаю подобных решений.
Ответы (15)
15
quq_CCCP, что бы выгружать одним аргументом.
GetStr( "text" )например.
Для спеллов которые на таймере.
15
LastUchiha, ну в спелле я могу к примеру выгрузить время, даммика, кастера. Например кастер выгружается первым, и в нём происходит запись хэндл айди таймера, для следующих выгрузок вызывать GetHandleId не понадобится, так как оно будет записано в темповую переменную для айдишников.
30
quq_CCCP, это дефолт обёртка над хт
globals
	hashtable HT // текущая таблица
	integer HI // текуший главный ключ таблицы
endglobals

function GetInt takes integer k return integer
	return GetSavedInteger(HT, HI, k)
endfunction
// ... пачка функций на каждый тип

function callback takes nothing returns nothing
	set HT = SomeHashtable
	set HI = GetHandleInd(GetExpiredTimer())

	set myInt = GetInt(1)
	set myStr = GetStr(22)
	//...

endfunction
15
nazarpunk, ну вот, а я хотел уместить set HI = GetHandleInd(GetExpiredTimer()), в функцию которая делает GetHandleInd(GetExpiredTimer()). Только что свой способ попробовал, и словил перезапись данных, что очень странно.
30
LastUchiha, потому что мне лень вспоминать как нативка зовётся. По коду основная мысль и так понятна.
30
Только что свой способ попробовал, и словил перезапись данных, что очень странно.
Я выше привёл классический, безотказный способ. Но нужно же обязательно изобрести велосипед.
15
nazarpunk, а если я спеллы пишу на локалках? Я же не могу сетнуть глобалку выше объявления локалок.
30
Я же не могу сетнуть глобалку выше объявления локалок.
Правда? А ты моск для этого пытался использовать?
globals
	hashtable HT // текущая таблица
	integer HI // текуший главный ключ таблицы
endglobals

function GetInt takes integer k return integer
	return GetSavedInteger(HT, HI, k)
endfunction
// ... пачка функций на каждый тип

function GetTimerId takes hashtable ht returns integer
	set HT = ht
	set HI = GetHandleInd(GetExpiredTimer())
	return HI	
endfunction

function callback takes nothing returns nothing
	local integer id = GetTimerId(SomeHashtable)

	local integer myInt = GetInt(1)
	local string myStr = GetStr(22)
	//...

endfunction
15
nazarpunk, на самом деле не пытался))), но и лишний раз интегерную переменную создавать не хочеца.
30
но и лишний раз интегерную переменную создавать не хочеца.
Тебя в детстве интегеры обижали?
15
nazarpunk, ну типо какой то след в памяти оно же оставит.
30
LastUchiha, у тебя остальной код настолько вылизан, что один integer внесёт значимый вклад?
Ну а если ты упоролся в производительность, то знай - самые быстрые функции это те, которые не имеют аргументов и локалок. Живи теперь с этим.
Этот комментарий удален
19
Вместо того, чтобы гадать, можно провести замеры.
Я делал мод, который добавляет нативки для бенчмарков — просто кинь JassApi.dll и
natives.mix в папку с игрой и объяви в коде нативки:
native GetTickCount takes nothing returns integer
native SetOperationLimitEnabled takes boolean state returns nothing
native IsOperationLimitEnabled takes nothing returns boolean
После чего сделай функцию, которая многократно выполняет интересующее тебя действие и засеки время до и после исполнения, затем вычисли разницу.
Важно сделать так, чтобы функция исполнялась достаточно долго для того, чтобы погрешность была не слишком велика. Измерять одно действие смысла мало, а вот повторить его миллион раз уже может иметь смысл, чтобы на выполнение задачи ушли секунды, а не наносекунды, что может привести к погрешности ±100%.
Не забудь отключить лимит операций с помощью вызова SetOperationLimitEnabled(false), а иначе виртуальная машина убьет поток из-за превышения лимита.
Принятый ответ
Ответы (3)
15
IceFog, это можно будет в цикле делать очень очень очень много действий?
19
LastUchiha, учти, что цикл также будет исполнять свои инструкции для проверки условий и прыжков. Можешь посмотреть во что компилируется функция при помощи JassView. Метки для прыжков это тоже инструкции, но которые ничего не делают и интерпретатор игнорирует их.
Если хочешь, чтобы накладные расходы цикла не сильно влияли на результат, то можешь совершать действие в его теле достаточно много раз, чтобы затенить их.
пример
function BenchmarkComparison takes nothing returns nothing
local integer i = 0
local integer start
local integer elapsed
	call SetOperationLimitEnabled(false)
	set start = GetTickCount()

	loop
		exitwhen i > 1000000
		// ТВОЁ ДЕЙСТВИЕ
		// ТВОЁ ДЕЙСТВИЕ
		// ...
		set i = i + 1
	endloop

	set elapsed = GetTickCount() - start
	call BJDebugMsg("Time elapsed: " + R2S(elapsed / 1000.0) + " seconds.")
endfunction
Можно сделать два варианта действия для этой функции:
1
if MUIID == 0 then
	set MUIID = GetHandleId( GetExpiredTimer() )
endif
2
GetHandleId( GetExpiredTimer() )
Затем сравни их время исполнения.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.