Elengar Posted December 2, 2014 Share Posted December 2, 2014 Пожалуйста, объясните кто-то что дает нам как бы ООП добавленное в 1.4, что нового можно сделать с помощью него, а то туторы понимаю, а что с ним делать не понимаю. А еще оно, почему-то, работает 2 раза медленнее... Результаты бенчмарков можно увидеть? В каком месте медленнее, какие тесты проводились и вообще откуда такие заявления? Возможно, я не правильно замеряю время. Да и вообще, я сейчас запустил опять то, чем раньше это замерял... Результаты какие-то совсем странные. Раньше они были почти одинаковые, теперь совсем не одинаковые, 1-2 из 10 в случайном порядке вообще, почему-то, секунду выполняются... Опишите правильный способ замера заодно. Link to comment
Kenix Posted December 2, 2014 Share Posted December 2, 2014 getTickCount Разница во времени между участками кода и будет ответом. Link to comment
Other Languages Moderators Disinterpreter Posted December 2, 2014 Other Languages Moderators Share Posted December 2, 2014 Классы вместо процедур? Методы жи Link to comment
Other Languages Moderators Disinterpreter Posted December 2, 2014 Other Languages Moderators Share Posted December 2, 2014 Пожалуйста, объясните кто-то что дает нам как бы ООП добавленное в 1.4, что нового можно сделать с помощью него, а то туторы понимаю, а что с ним делать не понимаю. А еще оно, почему-то, работает 2 раза медленнее... Lua раз в 10 мделеннее чем asm и всё ровно на ней пишут. Link to comment
Elengar Posted December 2, 2014 Share Posted December 2, 2014 getTickCount Разница во времени между участками кода и будет ответом. Ну, тогда у меня всё правильно. Но странность с результатами всё же осталась... И ООП, всё же, медленнее, не в 2 раза, но медленнее. Lua раз в 10 мделеннее чем asm и всё ровно на ней пишут. Ну, и если бы оно реально в 2 раза медленнее было, можно было просто написать компилятор(как MoonScript) из такого ООП в процедурное. Это не так уж и сложно. Link to comment
Kernell Posted December 2, 2014 Share Posted December 2, 2014 getTickCount Разница во времени между участками кода и будет ответом. Ну, тогда у меня всё правильно. Но странность с результатами всё же осталась... И ООП, всё же, медленнее, не в 2 раза, но медленнее. Lua раз в 10 мделеннее чем asm и всё ровно на ней пишут. Ну, и если бы оно реально в 2 раза медленнее было, можно было просто написать компилятор(как MoonScript) из такого ООП в процедурное. Это не так уж и сложно. Просто ООП в Lua работает как костыль, поэтому это и есть лишь имитация ООП, и никак иначе. Сравнение с MoonScript не совсем корректное, то о чём ты говоришь - не копилятор, а скорее конвертор, но мыль я твою понял. Конечно было бы хорошо иметь компилятор для Lua, который бы приводил всё в байткод как и сейчас. Хотя, написать транслятор из C# в Lua с последующей компиляцией (mta_luac) тоже не плохой вариант Link to comment
Elengar Posted December 2, 2014 Share Posted December 2, 2014 Просто ООП в Lua работает как костыль, поэтому это и есть лишь имитация ООП, и никак иначе. Сравнение с MoonScript не совсем корректное, то о чём ты говоришь - не копилятор, а скорее конвертор, но мыль я твою понял. Конечно было бы хорошо иметь компилятор для Lua, который бы приводил всё в байткод как и сейчас. Хотя, написать транслятор из C# в Lua с последующей компиляцией (mta_luac) тоже не плохой вариант Ну, я тоже не хотел это компилятором называть, но на сайте MoonScript'a написано MoonScript is a dynamic scripting language that compiles into Lua. А на сайте CoffeeScript'а тоже написано подобное CoffeeScript is a little language that compiles into JavaScript. А как C# сможет транслироваться в Lua, если в нем очень много того, что в Lua не возможно сделать ? Link to comment
Other Languages Moderators Disinterpreter Posted December 2, 2014 Other Languages Moderators Share Posted December 2, 2014 МунСкрипт как и КоффиСкрипт это всего лишь синтаксический сахар, чего вы тут напридумывали, компиляторы какие-то. Link to comment
Elengar Posted December 2, 2014 Share Posted December 2, 2014 МунСкрипт как и КоффиСкрипт это всего лишь синтаксический сахар, чего вы тут напридумывали, компиляторы какие-то. Синтаксический сахар, это когда в язык вводят разные(мб упрощенные) способы задать что-то(как в С++14 разделение 100'000'00), а Мун и Коффе скрипты - языка программирования, которые компилируются(я думаю, что можно это так назвать, если подразумевать некоторое трансформаировани в более "реальный" вид) в Lua Да, относительно Lua, MoonScript это Lua c синтаксическим сахаром, но сам по себе он язык программирования. Link to comment
lil Toady Posted December 3, 2014 Share Posted December 3, 2014 Компиляция Lua скриптов никак не ускорит их выполнение, лишь загрузку. Текстовый скрипт и так переводится в байт код при загрузке. На счет ООП в Lua - выполнение одной функции скорее будет быстрее процедурно (хотя тут зависит от того сколько у нас глобальных переменных, сколько функций в классе, и на каком уровне наследования находится функция). Тупо потому что при обращении, идет поиск функции в таблице по строковому названию: moo() - это то же самое что и _G["moo"]() Но смысл в том что за счет большей абстракции в ООП, общая логика для достижения того же результата будет меньше (уже есть примеры, freecam переписанный на ооп в несколько раз меньше, с тем же функционалом) В ирке я выдвинул на обсуждение небольшое изменение нынешней структуры метатаблиц. А именно: перенос наследственности на уровень таблицы класса и перенос свойств (переменных) туда же, для тех кто шарит, мой пример будет понятен: Element = { setHealth = ..., getHealth = ..., health = { __set = ... __get = ... }, ... } Vehicle = { func = ..., ... } setmetatable ( Vehicle, { __index = Element } ) Это и ускорит поиск, по сравнению с нынешним; упростит наследование от элементов МТА; упростит создание своих свойств объекта. Link to comment
Narrator Posted December 8, 2014 Share Posted December 8, 2014 Народ, я люблю использовать сложные конструкции вместо кучи переменных, например, это: setElementPosition(value, split(dataTable[1]["playerPosition"], ",")[1], split(dataTable[1]["playerPosition"], ",")[2], split(dataTable[1]["playerPosition"], ",")[3]) Вместо этого: local string = dataTable[1]["playerPosition"] local splitString = split(string, ",") setElementPosition(value, splitString[1], splitString[2], splitString[3]) Это самый ближний пример, порой мои конструкции получаются очень длинными Вопрос: Влияет ли мой подход на производительность лучше или хуже? Что предпочитаете вы? Link to comment
Elengar Posted December 8, 2014 Share Posted December 8, 2014 Народ, я люблю использовать сложные конструкции вместо кучи переменных, например, это: setElementPosition(value, split(dataTable[1]["playerPosition"], ",")[1], split(dataTable[1]["playerPosition"], ",")[2], split(dataTable[1]["playerPosition"], ",")[3]) Вместо этого: local string = dataTable[1]["playerPosition"] local splitString = split(string, ",") setElementPosition(value, splitString[1], splitString[2], splitString[3]) Это самый ближний пример, порой мои конструкции получаются очень длинными Вопрос: Влияет ли мой подход на производительность лучше или хуже? Что предпочитаете вы? Влияет. Ты 3 раза вычисляешь одно и то же(split(dataTable[1]["playerPosition"], ",")). Можно, кстати, так local splitString = split(dataTable[1]["playerPosition"], ",") setElementPosition(value, splitString[1], splitString[2], splitString[3]) Link to comment
Narrator Posted December 8, 2014 Share Posted December 8, 2014 Elengar, Да, я знаю, что так можно, я в качестве примера специально более громоздкую конструкцию привел. А не выполняется ли функция, которая присвоена переменной каждый раз, когда обращаются к переменной? Я об этом. А о том, что на первый взгляд первый вариант кажется более ресурсоемким я и сам догадался UPD: Не выполняется, проверил: function retRandom() return math.random(1, 9999) end local count = retRandom() print (count) print (count) print (count) print (count) Link to comment
Elengar Posted December 8, 2014 Share Posted December 8, 2014 Elengar, Да, я знаю, что так можно, я в качестве примера специально более громоздкую конструкцию привел. А не выполняется ли функция, которая присвоена переменной каждый раз, когда обращаются к переменной? Я об этом. А о том, что на первый взгляд первый вариант кажется более ресурсоемким я и сам догадался UPD: Не выполняется, проверил: function retRandom() return math.random(1, 9999) end local count = retRandom() print (count) print (count) print (count) print (count) Для простеньких тестов в чистом Lua есть os.clock(), а в МТА getTickCount() Сохраняешь результат этой функции в переменную до нужных операций, после - от нового результата выполнения функции этот результат . local t = getTickCount() local splitString = split(dataTable[1]["playerPosition"], ",") setElementPosition(value, splitString[1], splitString[2], splitString[3]) outputChatBox(getTickCount() - t) Только для замера их нужно выполнять в цикле, иногда и по 1000 раз, т.к. результат выполнения десятка простых операций может дать 0. Link to comment
Narrator Posted December 8, 2014 Share Posted December 8, 2014 Elengar, спасибо) что-то я не догадался так протестить) Link to comment
FranklinRoosevelt Posted December 8, 2014 Share Posted December 8, 2014 Для простеньких тестов в чистом Lua есть os.clock(), а в МТА getTickCount() Сохраняешь результат этой функции в переменную до нужных операций, после - от нового результата выполнения функции этот результат . local t = getTickCount() local splitString = split(dataTable[1]["playerPosition"], ",") setElementPosition(value, splitString[1], splitString[2], splitString[3]) outputChatBox(getTickCount() - t) Только для замера их нужно выполнять в цикле, иногда и по 1000 раз, т.к. результат выполнения десятка простых операций может дать 0. На счет подставить в цикл реально крутая и простая идея, но я тоже не додумывался о таком, а то много что замеряю и дает 0. Link to comment
lil Toady Posted December 9, 2014 Share Posted December 9, 2014 setElementPosition ( value, unpack ( split ( dataTable[1]["playerPosition"], "," ) ) ) Link to comment
Narrator Posted December 9, 2014 Share Posted December 9, 2014 lil Toady, большое спасибо, хороший пример) Радует, что ты стал чаще сюда заглядывать) Link to comment
Narrator Posted December 9, 2014 Share Posted December 9, 2014 Народ, вопрос к тем, кто использует серверные таблицы для хранения данных игроков. Является ли такой способ получения данных на клиенте оптимальным? А то его использование приводит к костылям при работе с интерфейсом. Триггер с клиента на сервер с запросом данных -> обработка и триггер с сервера на клиент с возвращением данных Это, пока что единственное обстоятельство, которое не дает пользоваться серверными таблицами, ведь порой нужно получить результат в одной функции, а этот способ подразумевает две. Link to comment
FranklinRoosevelt Posted December 9, 2014 Share Posted December 9, 2014 Триггер с клиента на сервер с запросом данных -> обработка и триггер с сервера на клиент с возвращением данных Я сделал так что при всех изменениях на сервере запускаются триггеры на клиент с измененными данными. Интересно узнать, может есть метод более эффективнее. Link to comment
Kernell Posted December 9, 2014 Share Posted December 9, 2014 Народ, вопрос к тем, кто использует серверные таблицы для хранения данных игроков. Является ли такой способ получения данных на клиенте оптимальным? А то его использование приводит к костылям при работе с интерфейсом. Триггер с клиента на сервер с запросом данных -> обработка и триггер с сервера на клиент с возвращением данных Это, пока что единственное обстоятельство, которое не дает пользоваться серверными таблицами, ведь порой нужно получить результат в одной функции, а этот способ подразумевает две. Это вполне нормально. Как иначе ты себе представляешь получение необходимых данных с сервера? Ты хочешь чтобы у тебя функция делала запрос на сервер и сразу же возвращала результат (аля mysql_query в PHP\плагине)? - А ты в курсе, что это возможно только блокировкой твоего потока в целях ожидания пока пакет дойдёт до сервера, далее пройдёт обработка запроса, пойдёт пакет обратно и лишь только тогда поток разблокируется? Все скрипты выполняются в одном потоке. Касательно mysql_query из модуля MTA MySQL: пока запрос выполняется и ожидается возврат результата - поток на сервере стоит. Именно поэтому рекомендуется использовать встроенные функции, так как там есть возможность повесить каллбек. Конечно же на сервере это не так страшно как на клиенте. Link to comment
Narrator Posted December 10, 2014 Share Posted December 10, 2014 (edited) Kernell, спасибо) Edited December 10, 2014 by Guest Link to comment
lil Toady Posted December 10, 2014 Share Posted December 10, 2014 Ну неправда же. Вполне можно сделать чтобы функция делала запрос к серверу, получала ответ и выдавала результат там где выполняется - coroutine. Для db функций тоже можно использовать. В итоге все будет очень красиво и удобно, но для этого нужно чтобы обработчики событий выполнялись в короутинах, соответственно addEventHandler лучше обернуть, вместе с removeEventHandler и т.д. Принцип таков: - вызывается событие (ткнули в кнопку рефреш в окне, например); - создается новый короутин; - короутин запускается с аргументами события; - где-то понадобилось запросить данные с сервера, вызывается функция, скажем getServerData(); - getServerData делает triggerServerEvent на сервер, записывает в промежуточную таблицу (например requests) что такой-то короутин ждет ответа от сервера; - сервер обрабатывает запрос, отвечает с triggerClientEvent - клиент ловит ответ, берет из таблицы requests короутин который этот ответ ждал, передает в него результат и продолжает его (coroutine.resume) В итоге в коде все будет оч красиво: addEventHandler ( "onClientGuiClick", refreshbutton, function () ... local data = getServerData () -- в этой функции сделается запрос к серверу и вернутся данные, выполнение остановится, пока данные не придут -- заполняем гуи ... end, false ) Для примера, вот небольшой враппер для db функций, где db.query возвращает результат там где выполняется, а не в колбек: тык local users = db.query ( "select * from users" ); А тут пример враппера с короутинами для евентов (правда чуть кривой): тык Link to comment
Kernell Posted December 10, 2014 Share Posted December 10, 2014 Ну неправда же. Что именно не правда? Что поток замораживается во время выполнения или что? Вполне можно сделать чтобы функция делала запрос к серверу, получала ответ и выдавала результат А я говорил что этого нельзя сделать? По факту это та же самая блокировка потока, только тут скорее речь про псевдопоток, но тем не менее, костыль вполне себе годный. Link to comment
lil Toady Posted December 11, 2014 Share Posted December 11, 2014 Костыль? Это то, для чего короутины вообще существуют. Невозможно в Lua добавить потоки, в привычном их виде, Lua не thread-safe. Да и смысла нет, весь API абсолютно event based, все скрипты - это обработчики каких-либо событий. Сами по себе они не существуют. Link to comment
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now