Это популярное сообщение. Dennis_Chikin 3 658 Опубликовано 22 Ноября 2014 Это популярное сообщение. Поделиться Опубликовано 22 Ноября 2014 А теперь мы попытаемся со всей этой фигней взлететь ! (С)Собственно, чтобы заработало без каких-либо переделок все остальное, что я сюда вкладываю.Скрипт большой и толстый, так что этого слона мы будем есть по частям и долго.Тему создал, чтобы болталась мне здесь немым укором, и напоминала. 3 1 3 Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Ссылка на комментарий
Dennis_Chikin 3 658 Опубликовано 23 Ноября 2014 Автор Поделиться Опубликовано 23 Ноября 2014 (изменено) Поехали.Вообще, удивительно, как нечто уродливое тянут из мода в мод, навешивая на него дополнительных уродств с целью некоей непонятной совместимости с неизвестно с чем, и на подобие тех мышей из анекдота про кактус продолжают попытки совмещений несовмещаемого в одном флаконе, подстраивая все подряд под это самое уродство.Вместо того, чтобы давно написать быструю, удобную, безглючную и, главное, действительно универсальную базу, а потом уже спокойно делать все под нее.Сейчас я начну переписывать скрипт прямо "по живому", так что ревью, тесты и дополнения приветствуются, и, надеюсь, общими усилиями что-нибудь все-таки сделаем.первый кусок: if ( jit == nil ) then profiler.setup_hook() end string_sub, string_gsub = string.sub, string.gsub string_find, string_gfind = string.find, string.gfind string_match, string_gmatch = string.match, string.gmatch string_format, string_char = string.format, string.char string_len = string.len -- dc: а # - некошерно ? table_insert, table_remove, table_foreach = table.insert, table.remove, table.foreach math_random, math_randomseed = math.random, math.randomseed math_sin, math_cos, math_acos = math.sin, math.cos, math.acos math_floor, math_ceil = math.floor, math.ceil math_mod, math_sqrt = math.mod, math.sqrt function round( value ) local min = math_floor( value ) local max = min + 1 -- if value - min > max - value then return max end -- dc: приведем к "<, ==, >=" if ( value - min ) < ( max - value ) then return min end return max end function to_str( v ) if type( v ) == "userdata" then local n = v.name return ( type( n ) == "function" and ( "userdata[" .. v:name() .. "]" ) ) or ( type( n ) == "string" and ( "userdata[" .. n .. "]" ) ) or "*userdata*" elseif v == nil then return "<nil>" -- dc: именно "<nil>" - для извращенцев end return tostring( v ) end function log( ct, fmt, ... ) -- src - откуда вызван, если false - не выводится, категория игнорируется -- get_console():execute( "load ~" .. ct .. "~ [_g] " .. ( fmt or "" ) ) -- для поиска потерянных аргументов и скрипта, их потерявшего get_console():execute( "load ~" .. ct .. "~ [_g] " .. ( ( ... and string_format( fmt, ... ) ) or fmt or "" ) ) if ct == "error" or ct == "log" then get_console():execute( "flush" ) end end function abort( fmt, ... ) get_console():execute( string_format( "load ~error~: %s", ( ... and string_format( fmt, ... ) ) or fmt or "" ) ) get_console():execute( "load ~~~ Обнаружена ошибка. Описание ошибки смотрите выше. Игра остановлена." ) get_console():execute( "load ~~~ Пожалуйста, не надо сообщать об ошибке в строке 50." ) get_console():execute( "load ~~~ Какую-либо ценность имеют 10 строк ДО этого сообщения." ) get_console():execute( "flush" ) local a ; a = 1/a; get_console():execute( "quit" ) exit() end Библиотечные функции, как обычно, определяем локально. Иначе потом, в циклах, из этих микросекунд набегают секунды лагов.function round( value ) -- округление, которого не хватает в библиотеках. Там где-то в файле такая же болтается, но ее находим, выносим в начало, и переписываем, чтобы больше перед глазами не маячила, когда займемся прочим.function to_str( v ) -- преобразование аргумента в строку. Используется потом при работе с логикой, и где-то еще. nil и userdata на вход подавать НЕЛЬЗЯ, что бы там пысы не писали. Точнее, nil - еще можно, из логики, а userdata просто повиснет, или вылетит с бредом в логе. Это функция именно для логики. Для наших собственных нужд потом добавим такую же в отдельном скрипте. Упс ! Я ее, оказывается, уже успел переписать. Но тем не менее, все равно для логики.log() и abort() - отладочные. Соответственно, вывести что-то в лог и крэшнуть игру. Как и в случае с to_str() Здесь используются короткие, "world-wide совместимые" варианты. Более полезные определяются в более другом скрипте. А здесь главное - успеть вывести хоть что-то вменяемое, если где-то отработало что-то, до чего пока не добрались.Продолжение следует.Напоминаю, что куски, которые здесь будут - будут в виде, готовом сразу к переносу в ваши экземпляры скриптов без потери/нарушения работы ваших модов. Ну, я надеюсь.А если нет - надеюсь, мы их здесь все-таки доработаем до определенной универсальности. Изменено 23 Ноября 2014 пользователем Dennis_Chikin Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Ссылка на комментарий
Murarius 10 533 Опубликовано 23 Ноября 2014 Поделиться Опубликовано 23 Ноября 2014 Сейчас я начну переписывать скрипт прямо "по живому", так что ревью, тесты и дополнения приветствуются, и, надеюсь, общими усилиями что-нибудь все-таки сделаем. На заметку академикам: вот это именно то, что я и мечтал видеть, и только попробуйте Дениса не поддержать продуманными и содержательными постами ... 1 Литературка (избранное): "Координаты избушки" (2023) --- "Колобок времени" (2019) --- "Пиво и жлоб" (2018) --- "Лекарство против морщин" (2013) --- "Когда все пройдет" (2013) Креатив (бесперспективное): Dominanta --- Сон на земле Досвиданьице (слезное): Смена администратора (2024) Ссылка на комментарий
Dennis_Chikin 3 658 Опубликовано 23 Ноября 2014 Автор Поделиться Опубликовано 23 Ноября 2014 (изменено) Продолжаем разговор: sys_ini = system_ini() global_time_ms, game_time_ms, game_time_sec, game_time_time = 0, 0, 0, 0 game_time_start, game_time_base = 0, 0 -- игровое время на начало игры, игровое время при загрузке dist_sw_online = 150 dist_sw_offline = 180 IAmAStalker, IAmAMonster = {}, {} -- obsolete IAmAWeapon, IAmAWeaponFireOnly = {}, {} -- obsolete c_npc = false c_actor = false c_mob = {} c_ai = {} c_trader = false c_ibox = false c_wpn = {} c_arms = {} mob_online = {} -- табличка принудительного on/off-line для монстров force_offline = {} -- принудительный оффлайн для неписей и тайников function printf() end function print_table() end function trim( s ) return string_match( s, "^%s*(.*%S)" ) end -- обрезаем пробелы function Parse_StrToTbl( s, div, mode ) -- ( строка, разделитель, [true|число|nil для строк] ) local t = {} local pattern if div then pattern = "%s*([^" .. sDiv .. "]+)%s*" else pattern = "[_%w]+" end if mode then if mode == true then for v in string_gmatch( s, pattern ) do t[v] = true end -- таблица вида [значение] = true elseif type( mode ) == "number" then -- таблица вида [idx] = число for v in string_gmatch( s, pattern ) do table_insert( t, tonumber( v ) or v ) end else abort( "Parse_StrToTbl, ivalid mode: %s", tostring( mode ) ) end else for v in string_gmatch( s, pattern ) do table_insert( t, v ) end end return t end function parse_custom_data( str ) -- комментарии в профилях и cd не использовать ! Сохраняются в cd как есть ! local t = {} if str then --log( "info", "parse_custom_data: [" .. string_sub( str, 1, 150 ) .. "]" ) local ts for sect, data in string_gfind( str, "%s*%[([^%]]*)%]%s*([^%[%z]*)%s*" ) do --log( "info", "parse_custom_data, sect: [" .. sect .. "], data: [" .. string_sub( data or "nil", 1, 120 ) .. "]" ) ts = {} t[sect] = ts for s in string_gfind( data or "", "([^\n]*)\n*" ) do if string_find( s, "=" ) then for k, v in string_gfind( s, "([^=]-)%s*=%s*(.*)" ) do --log( "info", "parse_custom_data, " .. k .. " = " .. string_sub( v or "nil", 1, 120 ) ) if v then k = string_match( k, "^%s*(.*%S)" ) if k and k ~= "" then ts[k] = string_match( v, "^%s*(.*%S)" ) end end end else local k = string_match( s, "^%s*(.*%S)" ) if k and k ~= "" then ts[k] = "<<no_value>>" end end end end end return t end function gen_custom_data( t ) local s = "" for k, v in pairs( t ) do s = s .. "[" .. k .. "]\n" for kk, vv in pairs( v ) do if vv ~= "<<no_value>>" then s = s .. kk .. " = " .. vv .. "\n" else s = s .. kk .. "\n" end end end return s end function parse_names( s ) local t, n = {}, 0 for name in string_gfind( s, "([%w%-%._\\]+)[%,%s]*" ) do n = n + 1; t[n] = name end return t end function parse_key_value( s ) if s then local t = {} local k for n in string_gfind( s, "([%w%-%._\\]+)[%,%s]*" ) do if k then t[k] = n; k = nil else k = n end end return t end end function parse_nums( s ) local t, n = {}, 0 for entry in string_gfind( s, "([%d%.]+)%,*" ) do n = n + 1; t[n] = tonumber( entry ) end return t end sys_ini = system_ini() -- файлы в винде вообще открываются ОЧЕНЬ медленно. А сам сталкер еще и что-то с ними делает, тоже мееедленно, и печально. Отсюда и загрузка солянки по 2 минуты. Так что открываем все один раз, и так в открытом состоянии и держим. global_time_ms, game_time_ms, game_time_sec, game_time_time = 0, 0, 0, 0 game_time_start, game_time_base = 0, 0 -- игровое время на начало игры, игровое время при загрузке В общем, вместо времени 64 бит с многочисленными преобразованиями в таблицы и обратно я использую везде 32. Ага, 31 мая, 32 мая, и т.д. Чтобы такого не было - время всегда считается не от НИ, а от загрузки. И сохраняется дельта. А месяц топтаться на одной оркации без единого сэйва - вряд-ли кто будет. Ну и наконец, вместо медленного вызова функций и пересчета используем быстрое обращение к переменной. А обновляются они раз в 200ms - вполне достаточно, я считаю. dist_sw_online = 150 dist_sw_offline = 180 Опять же, чтобы не перечитывать и не пересчитывать постоянно - переменные. А из alife.ltx берем только при загрузке. IAmAStalker, IAmAMonster = {}, {} -- obsolete IAmAWeapon, IAmAWeaponFireOnly = {}, {} -- obsolete c_npc = false c_actor = false c_mob = {} c_ai = {} c_trader = false c_ibox = false c_wpn = {} c_arms = {} - то, которое устарело - это была одна из солянковских оптимизаций. Устарело. Просто не от всюду еще дочистил. Добавлены константы и таблички с классами. Инициализируются при старте, когда отработает class_regisrator и появится alife(). mob_online = {} -- табличка принудительного on/off-line для монстров force_offline = {} -- принудительный оффлайн для неписей и тайников Как бы понятно из названия. Единые таблицы для ВСЕХ скриптов, где применяется такой фокус. Хотя вообще-то на самом деле это плохой, негодный фокус, и он не нужен, но это уже другая тема. А так - в amk было переодевание и тайники, использовавшее convert_npc={}, еще где-то - need_be_online={} в se_monster, не знаю, зачем... Тысячи их. Все снести, где реально надо - заменить на единые глобальные. printf() и print_table() - затычки для недовычищенного и прочих разных гибридизаций ежа с ужом через 50 скриптов, гордо именуемых "адаптациями". И, наконец, преобразования разных забавных строк в разные забавные таблицы, и обратно. Часть - была и в оригинале, часть - во вножестве экземпляров в разных скриптах, и оригинальных, и которые см. про "адаптацию". Все собрано в одном месте и переписано. Тут важно понимать, что в LUA НЕТ инлайна, а следовательно, все равно все это будет работать медленно и печально, и прежде чем использовать какую-нибудь функцию преобразования чего-попало во что-нибудь еще, особенно, в цикле или апдейте - подумайте, а надо ли ? Ибо нет ничего более нелепого, и вызывающего содрогание, чем конструкция вида: local s = "1, 2, 3" local t = parse_nums( s ) local n1, n2, n3 for k, v in pairs( t ) do if k == 1 then n1 = v end; if k == 2 then n2 = v end; if k == 3 then n3 = v end; end Изменено 23 Ноября 2014 пользователем Dennis_Chikin 3 Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Ссылка на комментарий
KD87 718 Опубликовано 1 Декабря 2014 Поделиться Опубликовано 1 Декабря 2014 (изменено) sys_ini = system_ini() -- файлы в винде вообще открываются ОЧЕНЬ медленно. А сам сталкер еще и что-то с ними делает, тоже мееедленно, и печально. Тут ошибка. Сталкер загружает конфиги однократно, более их не выгружает, соответственно любые манипуляции с конфигами в скриптах не приводят к открытию каких-либо файлов. Более того, функция system_ini() есть возврат указателя CInifile *pSettings, что опять же не только не приводит ни к каким файловым действиям, но и с точки зрения производительности не стоит практически ничего. Т.е., код сам по себе как код, только разницы никакой - что так, что получать system_ini в произвольном месте в скриптах. Тут скорее вопрос стиля кодирования и здесь я целиком за. Изменено 1 Декабря 2014 пользователем KD87 1 1 Ссылка на комментарий
Dennis_Chikin 3 658 Опубликовано 1 Декабря 2014 Автор Поделиться Опубликовано 1 Декабря 2014 "возврат указателя CInifile *pSettings" Странно... Впрочем, все равно собирался стресс-тесты устраивать, заодно и проверю. Но ведь народ-то тоже подтверждает наличие эффекта от устранения пессимизации c system_ini() по каждому чиху... Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Ссылка на комментарий
KD87 718 Опубликовано 1 Декабря 2014 Поделиться Опубликовано 1 Декабря 2014 Ну сам же писал - в LUA функции не инлайнятся Вызов функции все же вызов функции. Видимо, это влияет. Ссылка на комментарий
Dennis_Chikin 3 658 Опубликовано 1 Декабря 2014 Автор Поделиться Опубликовано 1 Декабря 2014 (изменено) Ага: ! Cannot find saved game ~test~ [bind_stalker] ini1: 13829.931640625 ! Cannot find saved game ~test~ [bind_stalker] sys_ini: 7527.0874023438 ! Cannot find saved game ~test~ [bind_stalker] test: 517023.3125 ! Cannot find saved game ~test~ [bind_stalker] test_ini: 4946.7431640625 тупо копипастой наплодил: local pt1 = profile_timer() local ini1, test pt1:start() for i = 1, 10000 do ini1 = system_ini() test = ini1:r_bool( "test1", "bool_t" ) end pt1:stop() log( "test", "ini1: %s", pt1:time() ) local pt1 = profile_timer() local ini1, test pt1:start() for i = 1, 10000 do test = sys_ini:r_bool( "test1", "bool_t" ) end pt1:stop() log( "test", "sys_ini: %s", pt1:time() ) local pt1 = profile_timer() local ini1, test pt1:start() for i = 1, 10000 do ini1 = ini_file( "test.ltx" ) test = ini1:r_bool( "test1", "bool_t" ) end pt1:stop() log( "test", "test: %s", pt1:time() ) local pt1 = profile_timer() local ini1 = ini_file( "test.ltx" ) local test pt1:start() for i = 1, 10000 do test = ini1:r_bool( "test1", "bool_t" ) end pt1:stop() log( "test", "test_ini: %s", pt1:time() ) Собственно, вызов жрет. А вот с просто файлом, не system.ltx - форменный кошмар (это из 5 строк файл). Изменено 1 Декабря 2014 пользователем Dennis_Chikin Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Ссылка на комментарий
Kirgudu 1 217 Опубликовано 1 Декабря 2014 Поделиться Опубликовано 1 Декабря 2014 @Dennis_Chikin, а может не вызов жрёт, а использование лишней переменной? Попробуй сделать так: for i = 1, 10000 do test = system_ini():r_bool( "test1", "bool_t" ) end Инструмент Ссылка на комментарий
Dennis_Chikin 3 658 Опубликовано 1 Декабря 2014 Автор Поделиться Опубликовано 1 Декабря 2014 ! Cannot find saved game ~test~ [bind_stalker] ini1: 13623.260742188 ! Cannot find saved game ~test~ [bind_stalker] system_ini(): 12739.622070313 ! Cannot find saved game ~test~ [bind_stalker] sys_ini: 7462.7309570313 Лучше, но не на много. Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Ссылка на комментарий
KD87 718 Опубликовано 1 Декабря 2014 Поделиться Опубликовано 1 Декабря 2014 А вот с просто файлом, не system.ltx - форменный кошмар А он как раз грузится с диска, т.к. не закеширован при загрузке. Ссылка на комментарий
Карлан 1 049 Опубликовано 1 Декабря 2014 Поделиться Опубликовано 1 Декабря 2014 @KD87, т.е. если заинклюдить в сустем.лтх все файлы то будет нормально все, я правильно понял? Ссылка на комментарий
Dennis_Chikin 3 658 Опубликовано 1 Декабря 2014 Автор Поделиться Опубликовано 1 Декабря 2014 (изменено) Это торговлю-то с 17500 костюмами ? (Сорри за малопонятный большинству юмор.) Правильнее на самом деле уменьшить общее количество как конфигов, так и их объем. Многие просто не нужны, и тянутся/плодятся, по тому, как сказал ZD, что в степи стоит 10 метров стены с вмятинами от голов разработчиков из ПЫС. А вынос system_ini() в _g.script - это ловля 2-х микросекунд, но, в общем, их может быть много. Внезапно много. Изменено 1 Декабря 2014 пользователем Dennis_Chikin Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Ссылка на комментарий
KD87 718 Опубликовано 1 Декабря 2014 Поделиться Опубликовано 1 Декабря 2014 @Карлан, если заинклудить туда, то файл будет загружен только раз и время, затрачиваемое на его загрузку перенесется на старт игры. Но! Обращение к секциям в файле должно будет идти через system_ini(), никаких ini_file(). Вызов ini_file() ведет к чтению файла с диска в любом случае, насколько я понимаю. Ссылка на комментарий
RayTwitty 492 Опубликовано 2 Декабря 2014 Поделиться Опубликовано 2 Декабря 2014 (изменено) sys_ini = system_ini()Что "sys_ini = system_ini()", что и "оптимизации" навроде "math_random = math.random()" - никогда не видел профита от них. Тогда смысл? Изменено 2 Декабря 2014 пользователем Shadows Ссылка на комментарий
Dennis_Chikin 3 658 Опубликовано 2 Декабря 2014 Автор Поделиться Опубликовано 2 Декабря 2014 (изменено) Смысл - ровно в 2 раза. Не, там, где за один раз в игру - не жалко этих 2-х микросекунд. Но ведь отдельные гении ухитряются писать циклы наподобие приведенного, и все это - в 20 миллисекундном апдейте x 100 раз. А потом и получается "не может оно за 5 секунд выполняться, если на моем 16-ядерном пентиуме-666 на 100500Терагерц с терабайтом памяти и плазменной панелью на всю стену в кредит взятой - 2 минуты ! И вообще, кто плазменную панель в кредит не купил - тому надо вообще запретить на форум писать !!!" Короче, замеры - выше, код - выше. Изменено 2 Декабря 2014 пользователем Dennis_Chikin Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Ссылка на комментарий
RayTwitty 492 Опубликовано 2 Декабря 2014 Поделиться Опубликовано 2 Декабря 2014 (изменено) local pt = profile_timer() local sys_ini = system_ini() pt:start() for i = 1, 10000 do sys_ini:r_float("explosion_marks", "dist") end pt:stop() log1("1 ~~~ sys_ini time: "..pt:time()) pt:start() for i = 1, 10000 do system_ini():r_float("explosion_marks", "dist") end pt:stop() log1("2 ~~~ system_ini() time: "..pt:time())В главном меню игры. [12/02/14 14:03:05] 1 ~~~ sys_ini time: 6490.5009765625 [12/02/14 14:03:05] 2 ~~~ system_ini() time: 17246.419921875 [12/02/14 14:03:20] 1 ~~~ sys_ini time: 5242.6943359375 [12/02/14 14:03:20] 2 ~~~ system_ini() time: 13490.841796875 [12/02/14 14:03:31] 1 ~~~ sys_ini time: 5106.6259765625 [12/02/14 14:03:31] 2 ~~~ system_ini() time: 14303.36328125 [12/02/14 14:03:43] 1 ~~~ sys_ini time: 5217.56640625 [12/02/14 14:03:43] 2 ~~~ system_ini() time: 13807.4453125 [12/02/14 14:04:04] 1 ~~~ sys_ini time: 5126.4877929688 [12/02/14 14:04:04] 2 ~~~ system_ini() time: 18833.763671875 [12/02/14 14:04:51] 1 ~~~ sys_ini time: 5214.3110351563 [12/02/14 14:04:52] 2 ~~~ system_ini() time: 13137.846679688 [12/02/14 14:04:57] 1 ~~~ sys_ini time: 5111.0854492188 [12/02/14 14:04:57] 2 ~~~ system_ini() time: 12934.647460938 [12/02/14 14:04:57] 1 ~~~ sys_ini time: 5214.4775390625 [12/02/14 14:04:57] 2 ~~~ system_ini() time: 13486.434570313Разница конечно есть, в среднем 5 миллисекунд... Но учитывая, что это всего лишь 1/8 времени апдейта актора, да и читать 10 тыс. параметров вряд ли кто будет - полезность этой оптимизации стремится к нулю. local pt = profile_timer() local math_random = math.random pt:start() for i = 1, 10000 do math_random(5) end pt:stop() log1("1 ~~~ math_random time: "..pt:time()) pt:start() for i = 1, 10000 do math.random(5) end pt:stop() log1("2 ~~~ math.random time: "..pt:time())Результаты: [12/02/14 14:20:31] 1 ~~~ math_random time: 456.19830322266 [12/02/14 14:20:31] 2 ~~~ math.random time: 1170.6983642578 [12/02/14 14:20:44] 1 ~~~ math_random time: 434.591796875 [12/02/14 14:20:44] 2 ~~~ math.random time: 1108.9953613281 [12/02/14 14:20:55] 1 ~~~ math_random time: 429.08001708984 [12/02/14 14:20:55] 2 ~~~ math.random time: 1104.5678710938 [12/02/14 14:21:25] 1 ~~~ math_random time: 434.51354980469 [12/02/14 14:21:25] 2 ~~~ math.random time: 1108.9071044922 [12/02/14 14:21:27] 1 ~~~ math_random time: 437.62692260742 [12/02/14 14:21:27] 2 ~~~ math.random time: 1111.55102539060.7 миллисекунд на 10 тыс. генераций Вообщем, как обычно, в синтетических тестах вроде как изменения какие-то есть, но на деле роли не играют совершенно. Кривость кода надо в других местах лечить, а не подобными "оптимизациями". Изменено 2 Декабря 2014 пользователем Shadows Ссылка на комментарий
Desertir 202 Опубликовано 2 Декабря 2014 Поделиться Опубликовано 2 Декабря 2014 (изменено) , а разве таймер сбрасывается после pt:stop() или pt:start()? Если нет, то разница посчитана неверно, она вообще будет ничтожной Если все таки сбрасывается, пардонте. Сейчас еще раз посмотрел, если вы боретесь за мс, то стОит делать переменные глобальными, как в _g.script, а не как в тестах, хотя что тут говорить, оптимизировать надо явно другие места, это действительно нужно только для рефакторинга. Изменено 2 Декабря 2014 пользователем Desertir ТЧ 1.0004. SAP и Trans mod github Ссылка на комментарий
Desertir 202 Опубликовано 2 Декабря 2014 Поделиться Опубликовано 2 Декабря 2014 (изменено) Забавы ради вот вам local c = get_console() local log = function(v) c:execute(v) end local pt = profile_timer() _G.global_rnd = math.random local local_rnd = math.random rnd = math.random pt:start() for i = 1, 10000 do math.random(5) end pt:stop() log("math.random:"..pt:time()) pt = profile_timer() pt:start() for i = 1, 10000 do _G.global_rnd(5) end pt:stop() log("_G.global_rnd:"..pt:time()) pt = profile_timer() pt:start() for i = 1, 10000 do global_rnd(5) end pt:stop() log("global_rnd:"..pt:time()) pt = profile_timer() pt:start() for i = 1, 10000 do local_rnd(5) end pt:stop() log("local_rnd:"..pt:time()) pt = profile_timer() pt:start() for i = 1, 10000 do rnd(5) end pt:stop() log("rnd:"..pt:time()) math.random: 578.04058837891 _G.global_rnd: 600.54803466797 global_rnd: 576.27471923828 local_rnd: 398.26226806641 rnd: 487.28372192383 math.random: 656.1162109375 _G.global_rnd: 597.26733398438 global_rnd: 598.79229736328 local_rnd: 393.96237182617 rnd: 448.24282836914 math.random: 673.52966308594 _G.global_rnd: 606.00970458984 global_rnd: 579.37286376953 local_rnd: 393.57550048828 rnd: 460.28140258789 math.random: 670.90179443359 _G.global_rnd: 661.83203125 global_rnd: 569.04602050781 local_rnd: 423.73452758789 rnd: 426.40435791016 math.random: 610.52740478516 _G.global_rnd: 586.79565429688 global_rnd: 583.48901367188 local_rnd: 405.59097290039 rnd: 459.96835327148 Видим, что "родное" обращение, как и объявление ее глобальной + обращение через _G или просто по имени в целом одинаковы. Локальные несколько быстрее, но это все ерунда. Вот систим_ини local c = get_console() local log = function(v) c:execute(v) end _G.gsi = system_ini() local si = system_ini() local pt = profile_timer() pt:start() for i = 1, 10000 do system_ini():r_float("explosion_marks", "dist") end pt:stop() log("system_ini():"..pt:time()) pt = profile_timer() pt:start() for i = 1, 10000 do gsi:r_float("explosion_marks", "dist") end pt:stop() log("_G.gsi:"..pt:time()) pt = profile_timer() pt:start() for i = 1, 10000 do si:r_float("explosion_marks", "dist") end pt:stop() log("si:"..pt:time()) system_ini(): 7409.6904296875 _G.gsi: 5028.5361328125 si: 4695.3427734375 system_ini(): 8477.212890625 _G.gsi: 4900.01953125 si: 4699.5888671875 system_ini(): 7485.7944335938 _G.gsi: 4935.0239257813 si: 4756.3041992188 system_ini(): 8623.6474609375 _G.gsi: 4963.302734375 si: 4659.6748046875 system_ini(): 7239.9951171875 _G.gsi: 4911.7875976563 si: 4597.4228515625 Изменено 2 Декабря 2014 пользователем Desertir ТЧ 1.0004. SAP и Trans mod github Ссылка на комментарий
Dennis_Chikin 3 658 Опубликовано 3 Декабря 2014 Автор Поделиться Опубликовано 3 Декабря 2014 В общем, продолжая тему, имеет смысл коснуться печальной истории одной пессимизации, но поскольку касается она в основном Солянки и разнообразных солянкоклонов, то закинул ее в более специализированное место: http://www.amk-team.ru/forum/index.php?showtopic=8830&p=896984 У кого такого нет - то просто имейте в виду, что такие грабли есть, а добавлять и заменять ни где ничего не надо. Из солянки же в конечном итоге ВСЕ это - хоть то, что было, хоть предлагаемое на замену, следует убрать. По мере истребления всех имеющихся ссылок на ЭТО. Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Ссылка на комментарий
Рекомендуемые сообщения
Создайте аккаунт или авторизуйтесь, чтобы оставить комментарий
Комментарии могут оставлять только зарегистрированные пользователи
Создать аккаунт
Зарегистрировать новый аккаунт в нашем сообществе. Это несложно!
Зарегистрировать новый аккаунтВойти
Есть аккаунт? Войти.
Войти