www.mudconnector.su

Национальный мадконнектор.
Текущее время: Сб сен 18, 2021 2:47 pm

Часовой пояс: UTC + 3 часа [ Летнее время ]




Начать новую тему Ответить на тему  [ Сообщений: 23 ]  На страницу Пред.  1, 2, 3  След.
Автор Сообщение
 Заголовок сообщения: Re: mud design-concepts (расширяемость)
СообщениеДобавлено: Пт ноя 19, 2010 10:27 pm 
Не в сети

Зарегистрирован: Вт мар 24, 2009 6:20 pm
Сообщений: 213
Эрендир, всё-таки вы неверно поняли, видимо
Lua - это встраиваемый язык, он существует в контексте вашего приложения, и следовательно, вы должны с ним взаимодействовать.

Именно для этого предназначено Lua C API

Когда вы хотите выполнить в Lua код
Код:
foo={}
for i = 1, 10^6 do
   foo.bar=10
end


из вашего C-приложения, вы должны написать:

Код:
char *code = "for i = 1, 10^6 do foo.bar = 10 end";
luaL_dostring(luaState, code);

Справка по lua_dostring

и это действительно будет выполняться недолго
почему?
потому что, надо понимать, что здесь происходит на самом деле:
1) вызов библиотеки луа, передача в неё одной строки (на это на самом деле тоже тратится время)
2) луа парзит строку (на это тратится время!!), но т.к. строка в данном случае недлинная, парзится она довольно быстро, и преобразуется в байт-код
3) луа выполняет полученный байт-код, и на это тоже тратится время, впрочем это уже происходит очень быстро

но наша задача в другом
наша задача заключается в том, чтобы передать наши объекты в луа
к примеру, у нас в c есть некий объект foo, у него есть свойство-массив с миллионом элементов:
int Bar[1000000];
мы должны создать такой же объект в луа
мы можем сделать это примерно так:

Код:
sprintf(code, "
  foo = {}
  foo.Bar[0] = %d
  foo.Bar[1] = %d
  foo.Bar[2] = %d
  foo.Bar[3] = %d
  foo.Bar[4] = %d
  --- ....
  foo.Bar[999999] = %d", foo.Bar[0], foo.Bar[1], foo.Bar[2], foo.Bar[3], ... foo.Bar[999999]);

luaL_dostring(luaState, code);


представьте, сколько луа будет парзить такую строку? :)
но, это еще не все!

на самом деле, в контексте мада, событий множество, все они дискретны, для каждого события должен быть отдельный вызов луа!!

поэтому, фактически, нельзя будет передать 1 гигантскую строку.
фактически, придется делать много вызовов. например, так:

Код:
for (int i = 1; i<10000; i++)
{
    sprintf(code, "
      foo = {}
      foo.Bar[%d] = %d
      foo.Bar[%d] = %d
      foo.Bar[%d] = %d
      foo.Bar[%d] = %d
      foo.Bar[%d] = %d
      --- ....
      foo.Bar[%d] = %d", i, foo.Bar[i], i+1, foo.Bar[i+1], i+2, foo.Bar[i+2], i+3, foo.Bar[i+3], ... i+9, foo.Bar[i+9]);

    luaL_dostring(luaState, code);
   
}

вот, теперь у нас еще вдобавок ко всему 10к вызовов.
и теперь это уже работает вообще страшно долго.

как раз чтобы таким образом не извращаться, для C API придумали функцию

lua_setfield

которая позволяет делать это всё быстрее
кароче идет работа напрямую с луа-стеком, минуя парзинг данных

и вот даже несмотря на все эти оптимизации, всё равно присваивание таблице 1 млн. значений, работает 7 секунд.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: mud design-concepts (расширяемость)
СообщениеДобавлено: Сб ноя 20, 2010 2:31 am 
Не в сети

Зарегистрирован: Вс ноя 16, 2008 9:04 pm
Сообщений: 89
я всё это как бы понимаю, хотя сам практически не занимался именно интеграцией Луа в Си.
Так вот, слегка порывшись по мануалам и прочим интернетам я родил следующий код:

Код:
#include <iostream>

extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}

void report_errors(lua_State *L, int status)
{
  if ( status!=0 ) {
    std::cerr << "-- " << lua_tostring(L, -1) << std::endl;
    lua_pop(L, 1); // remove error message
  }
}

int main(int argc, char** argv)
{
  for ( int n=1; n<argc; ++n ) {
    const char* file = argv[n];

  lua_State *L;
  L = L = luaL_newstate();
  luaL_openlibs(L);

  std::cerr << "-- Loading file: " << file << std::endl;
  int s = luaL_loadfile(L, file);
   
   
  lua_newtable(L);
  for (int i=0; i < 1000000; i++){
    lua_pushstring(L, "bar");
    lua_pushnumber(L, 10);
    lua_rawset(L, -3);
  }
  lua_setglobal(L, "foo");

  lua_newtable(L);
  for (int i=0; i < 1000000; i++){
    lua_pushnumber(L, i);
    lua_pushnumber(L, i*2);
    lua_rawset(L, -3);
  }
  lua_setglobal(L, "t");


    if ( s==0 ) {
      // execute Lua program
      s = lua_pcall(L, 0, LUA_MULTRET, 0);
    }

    report_errors(L, s);
    lua_close(L);
    std::cerr << std::endl;
  }

  return 0;
}

компилировать так:
Код:
g++ test.cpp -o test -pedantic -Os -Ipath/to/Lua/include/ -Lpath/to/Lua/lib/ -llua5.1


теперь нужен ещё test.lua:
Код:
print(foo)
print(foo.bar)
print(t)
print(t[1],t[999999])


запускать так:
Код:
test test.lua

выполнение кода длится 0.333 секунды, и это включая парсинг и компиляцию скрипта test.lua.
(незначительного прироста производительности можно добится использованием `lua_createtable(L,1000000,0);` для второй таблицы)

При всё при этом сначала 10^6 раз выполняется код из Вашей статьи (`Measure("LuaDLL.lua_settable", 1000000, () =>`), а потом ещё заполняется миллион разных полей для новой таблицы.

Что возвращает нас к моему утверждению: ни Луа, ни Lua C API не виноваты в том, что Ваша программа работает очень медленно.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: mud design-concepts (расширяемость)
СообщениеДобавлено: Сб ноя 20, 2010 4:22 am 
Не в сети

Зарегистрирован: Вт мар 24, 2009 6:20 pm
Сообщений: 213
вынужден признать, дело было, по всей видимости, действительно не в бобине (не в парзинге).
на самом деле спасибо большое, что открыли глаза на это заблуждение.

но проблемы с производительностью всё равно имеются.

я подготовил вот такой код (на основе Вашего):

Код:
#include <iostream>
#include <ctime>

extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}

int main(int argc, char** argv)
{

   lua_State *L;
   L = L = luaL_newstate();

   char s[255];

   lua_newtable(L);

   clock_t t0 = clock();
   for (int i=0; i < 1000000; i++){
      // тут тестим
   }

   clock_t t1 = clock();
   std::cout << "time: " << (double)(t1 - t0) / CLOCKS_PER_SEC << std::endl;

   lua_close(L);

}


вместо "// тут тестим", вписываю, последовательно, следующие вещи:

Код:
sprintf(s, "bar%d", i);
lua_pushstring(L, s);
lua_pushnumber(L, i*3);
lua_settable(L, -3);

time: 6.343

Опа! 6 секунд всплыло...
Но может, это sprintf?
Проверим:

Код:
sprintf(s, "bar%d", i);

time: 1.813

sprintf, да не совсем. 4.5 секунды остаётся на луа...
А ведь при этом, вариант:

Код:
lua_pushstring(L, "bar");
lua_pushnumber(L, i*3);
lua_settable(L, -3);

time: 0.265

работает очень быстро.
также быстро работает и вот такой вариант:

Код:
lua_pushnumber(L, i);
lua_pushnumber(L, i*3);
lua_settable(L, -3);

time: 0.281

, НО!!

Код:
lua_pushnumber(L, i*2);
lua_pushnumber(L, i);
lua_settable(L, -3);

time: 1.39

и еще:

Код:
lua_pushnumber(L, 1000000-i);
lua_pushnumber(L, i*3);
lua_settable(L, -3);

time: 0.968

Интересные, в целом, результаты.
К сожалению, нет особо времени смотреть, что там в луа происходит, но видимо какой то кэш или хэш у них там есть, на обращение к филду...

Это, на самом деле, очень хорошо, думаю, многие проблемы с производительностью можно решить, если держать пару глобальных переменных постоянно в стеке (типов монстр, предмет, и т.п.), и в дальнейшем использовать для передачи данных именно их, а не вновь создаваемые таблицы.

Резюмируя
Эрендир в конечном итоге оказался прав.
Пожалуй, проблемы с производительностью в луа не критичны даже для реализации выносных скиллов/спеллов.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: mud design-concepts (расширяемость)
СообщениеДобавлено: Сб ноя 20, 2010 4:57 am 
Не в сети

Зарегистрирован: Вс ноя 16, 2008 9:04 pm
Сообщений: 89
Рад, что мне удалось Вас убедить!

И теперь уже видимо [offtop]:
первый пример (`sprintf(s, "bar%d", i);`) можно ускорить примерно вдвое, если вместо lua_newtable(L); использовать lua_createtable(L,0,1000000);
также он естественно самый медленный: сначала в куче создаётся миллион строк вида "bar%d", а потом наша тестовая таблица последовательно раздувается (пересчитывается non-array часть) во время заполнения (это можно избежать с lua_createtable )
пример с заполнением каждого второго (i*2) индекса можно ускорить либо за счёт (временного) места (lua_createtable(L,2000000,0);) (и потом задержка на итерации GC), либо посчитать руками, какого размера array часть, и какого non-array будет у такой таблицы.
пример с заполнением с конца (1000000-i) ускоряется аналогично.
[/offtop]

[offtop]
И да, я сам не был уверен в результатах, пока не занялся тестами, и, признаться, увидев Ваш пост про 7 секунд поначалу испугался: я всё лелею мечту понемножечку доклепать движок на чистом Луа (+luasocket и т.п., ессно), и если бы он тормозил даже с 10 игроками, это было бы ну очень обидно ;)
[/offtop]


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: mud design-concepts (расширяемость)
СообщениеДобавлено: Сб ноя 20, 2010 9:31 am 
Не в сети

Зарегистрирован: Вт сен 14, 2010 6:06 pm
Сообщений: 393
Извините, я, как новичок в создании мадов, не знаю, Lua - специальный язык написанный для скриптинга мадов?

_________________
Кодер и билдер MUD Shaal (Мада Мир Шааль).


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: mud design-concepts (расширяемость)
СообщениеДобавлено: Сб ноя 20, 2010 6:17 pm 
Не в сети

Зарегистрирован: Вс ноя 16, 2008 9:04 pm
Сообщений: 89
http://www.google.com/search?q=lua


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: mud design-concepts (расширяемость)
СообщениеДобавлено: Вс ноя 21, 2010 12:45 am 
Не в сети

Зарегистрирован: Вт мар 24, 2009 6:20 pm
Сообщений: 213
LUA - это один из популярнейших встраиваемых языков для игр. Используется, в частности, в WOW.
Встраиваемый язык означает, что вы можете использовать луа в качестве языка для триггеров, или других нужд, предполагающих необходимость создания скриптов.

Эрендир писал(а):
первый пример (`sprintf(s, "bar%d", i);`) можно ускорить примерно вдвое, если вместо lua_newtable(L);...

Первый пример наиболее близок к реальности из всех перечисленных, однако, как я уже упоминал, всё-таки в реальности скорее будет что-нибудь типа 5к созданий таблицы с 20 полями. Всё-таки, один объект с 1 млн. полей это абстракция.
Так что выигрыша в производительности тут врядли удастся добиться именно с помощью lua_createtable.

Нет, тут надо по-другому действовать.
Объекты передаются строго определенных типов.
В частности, это мобы, комнаты, и предметы.
Причем, за один раз таблиц каждого вида может передаваться, наверное, не больше трех.
Например, FIGHT-триггер требует self и actor, оба типа "монстр".
С другой стороны, после отрабатывания триггера эти переменные становятся ненужными, а значит, их можно либо совсем удалить из кучи, либо использовать повторно.

Если заранее создать по 3 таблицы каждого возможного типа, сохранить их в некоторых глобальных переменных, и затем, при передаче данных использовать именно эти таблицы, то скорость работы, по всей видимости, должна увеличиться в сотни раз.

Эрендир писал(а):
я всё лелею мечту понемножечку доклепать движок на чистом Луа (+luasocket и т.п., ессно)

Может быть, это и реально, но очень напоминает забивание гвоздей микроскопом - только потому, что микроскоп нравится и с ним привычнее работать:)

Ну в самом деле, язык должен выбираться под нужды. Потому что язык - это инструмент. Хороший, подходящий инструмент увеличивает скорость работы, и качество работы, в разы и даже на порядки.

Ну банальный пример, в луа нет настоящего ООП, это не критично для скриптов, но это критично для большого проекта.
Наследование, инкапсуляция, полиморфизм - всё это помогает и в том, чтобы создать гибкий и легко расширяемый проект.
Строгая типизация (как в С++, С# и java) позволяет отловить многие ошибки на стадии компиляции. На самом деле компиляция - это первый юнит-тест! В луа с типизацией всё намного проще, хотя луа конечно получше в этом плане, чем, к примеру, перл.
Подготовленные и проверенные механизмы для юнит-тестов, руководства, мануалы, библиотеки, комьюнити - во всем этом С++, java и С# тоже выигрывают.
Ну и всякий синтаксический сахар, как например, Linq, Generic'и, перегрузка операторов...

Подумай:) Мад на луа это ж ведь как раз тот самый велосипед с квадратными колесами, который делает сейчас Харч, только в добавок ко всему ты лелеешь этот велосипед собрать при помощи микроскопа :)

Ребяты! Если вам интересно работать над мадом, если у вас есть светлая голова, давайте объединяться.
Да, при этом придется идти на уступки, учиться работать в команде, иногда - делать вещи, которые делать не очень хочется.
Но это полезные навыки, и на работе, и в семейной жизни, и вообще в жизни.

И главное, ведь есть совершенно реальный шанс прочувствовать и увидеть, что результат вашей работы оценен, используется и нравится конечным пользователям...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: mud design-concepts (расширяемость)
СообщениеДобавлено: Вс ноя 21, 2010 1:21 am 
Не в сети

Зарегистрирован: Вс ноя 16, 2008 9:04 pm
Сообщений: 89
Не буду спорить про микроскоп и прочие юнит-тесты... Поживём-увидим, как говорится. Или не увидим, если я и дальше буду лениться. :)

Одно замечание: Луа не акроним. Писать ЛУА неправильно. Луа означает Луна (по-португальски, емнип).

По-поводу комманды: опыт объединения исключительно через интернет, без каких-либо других объединяющих факторов лично у меня отрицательный. Причём, емнип, дважды. Правда и я тогда был помладше и глупее, но всё же настроение относительно таких команд скептическое.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: mud design-concepts (расширяемость)
СообщениеДобавлено: Вс ноя 21, 2010 1:47 am 
Не в сети

Зарегистрирован: Вт мар 24, 2009 6:20 pm
Сообщений: 213
Однако же, если программист, то всё равно куда от команды? Разве что в суппорт на какое нибудь производство, а это буэ страшное, лучше даже не соваться. Убивает мозги за полгода, гарантированно. Я уж не говорю про сисадминство...

Самое классное это конечно тимлидом в стартапах. Но, опять же, тимлид => команда :)

Нет, если хочется программировать, от команды никуда. Я прошел весь этот путь, начинал в Хьерварде, потом писал собственный мад в одиночку, потом в малой команде, потом еще один проект мада писали - тоже с парой ребят, ну в итоге пришел в Адан...

Причем, Хьервард был как раз неприятным опытом. Полгода не было у меня возможности вылезать в мад, прихожу через полгода, и мне говорят что-то типа такого: у нас новый главбилдер (мой бывший билдер), пиши ему письмо, он посмотрит твою зону.

На самом деле, всё очень зависит от руководителя проекта.

Но если вы видите, что к примеру в былинах куча народу работает, ну ведь неспроста? Значит, лидер там, с большой вероятностью, умелый.

И кстати, после Хьерварда я пришел практически к таким же выводам, и начал писать сам.
Но две попытки подряд для меня оказались достаточными, чтобы понять, что создание полномасштабного мада, это задача не для одного человека. Даже если движок за год накатать, а мир кто делать будет? А редактор мира? А справку? А баланс? А сайт?...

Даже, на самом деле, не для двух человек. И еще нельзя забывать современные реалии, когда мады уже вышли из пика своей популярности, и чтобы в них играли, придется немало усилий приложить.

Нет, никуда без команды в мадах, никуда.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: mud design-concepts (расширяемость)
СообщениеДобавлено: Вс ноя 21, 2010 2:34 am 
Не в сети

Зарегистрирован: Вс ноя 16, 2008 9:04 pm
Сообщений: 89
Цитата:
Однако же, если программист, то всё равно куда от команды?

а я не програмист ;)

Но опять же, я не против команды вообще, я против команды, собранной исключительно через интернет, т.к. опыт такого рода у меня печальный. Я рискну предположить, что в Былинах работает куча людей, потому что есть некое ядро, несколько человек, знакомых друг с другом в реале, условно "вокруг которых" держаться остальные члены команды.
Цитата:
понять, что создание полномасштабного мада, это задача не для одного человека.

О, я прекрасно отдаю себе в этом отчёт, и мой план примерно таков:
1. Сделать движок, минимальный кусочек мира, более-менее сбалансированную механику,справку на всё что есть.
2. Порекламировать такой набросок, позвать желающих в билдеры
3. ??????
4. PROFIT!!!

(самое сложное тут, несомненно, пункт 4 ;))

Пока же я нахожусь где-то в начале очередной итерации номера 1, части а: движок :)


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 23 ]  На страницу Пред.  1, 2, 3  След.

Часовой пояс: UTC + 3 часа [ Летнее время ]


Кто сейчас на конференции


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
cron