Добро пожаловать на Pro Pawn - Портал о PAWN-скриптинге.
Страница 2 из 4 ПерваяПервая 1 2 3 4 ПоследняяПоследняя
Показано с 11 по 20 из 35
  1. #11
    Аватар для punkochel
    Пользователь

    Статус
    Оффлайн
    Регистрация
    08.12.2018
    Адрес
    Россия
    Сообщений
    146
    Репутация:
    25 ±
    Верно, именно вот эти 10 секунд. Когда идет рестарт сервера, то вызывается OnPlayerDisconnect (Как ни странно), следовательно нужно предварительно отключить игроков от сервера с сохранением данных, а это как-раз таки цикл...
    Ну или можно прописывать так:


    Тему можно закрыть, узнал много полезного, но не все конечно что хотел.

  2. #12
    Аватар для DeimoS
    Модератор?

    Статус
    Оффлайн
    Регистрация
    27.01.2014
    Адрес
    Восточный Мордор
    Сообщений
    5,588
    Репутация:
    1984 ±
    Цитата Сообщение от punkochel Посмотреть сообщение
    Верно, именно вот эти 10 секунд. Когда идет рестарт сервера, то вызывается OnPlayerDisconnect (Как ни странно), следовательно нужно предварительно отключить игроков от сервера с сохранением данных, а это как-раз таки цикл...
    Ну или можно прописывать так:


    Тему можно закрыть, узнал много полезного, но не все конечно что хотел.
    Эмм, зачем кого-то отключать от сервера? Сервер сам всё это сделает, если рестарт будет производиться заложенными в это средствами - через команды "gmx" или "exit". Если же ты убиваешь серверный процесс на стороне хостинга, то твой код в любом случае не будет вызываться, так как сервер и не поймёт, что его собираются перезагружать.

    Если не всё, что хотел, узнал - задавай дополнительные вопросы.
    Связаться со мной в VK можно через личные сообщения этой группы
    Заказы не принимаю

    Широко известно, что идеи стоят 0.8333 цента каждая (исходя из рыночной цены 10 центов за дюжину).
    Великих идей полно, на них нет спроса.
    Воплощение идеи в законченную игру требует долгой работы,
    таланта, терпения и креативности, не говоря уж о затратах денег, времени и ресурсов.
    Предложить идею просто, воплотить – вот в чём проблема

    Steve Pavlina

  3. #13
    Аватар для Shaolinka
    Пользователь

    Статус
    Оффлайн
    Регистрация
    19.01.2020
    Сообщений
    69
    Репутация:
    8 ±
    Цитата Сообщение от punkochel Посмотреть сообщение
    Верно, именно вот эти 10 секунд. Когда идет рестарт сервера, то вызывается OnPlayerDisconnect (Как ни странно), следовательно нужно предварительно отключить игроков от сервера с сохранением данных, а это как-раз таки цикл...
    Ну или можно прописывать так:


    Тему можно закрыть, узнал много полезного, но не все конечно что хотел.
    Создай булевую переменную для каждого игрока, при рестарте пройдись по всем игрокам, присвоив значение той булевой переменной на true. При выходе сверяй, был ли ли отключен игрок с помощью рестарта. Если да - сохраняй его данные.

  4. #14
    Аватар для punkochel
    Пользователь

    Статус
    Оффлайн
    Регистрация
    08.12.2018
    Адрес
    Россия
    Сообщений
    146
    Репутация:
    25 ±
    Цитата Сообщение от DeimoS
    Ты не видишь ничего страшного, а твой сервер начнёт всё больше и больше памяти жрать, если ты будешь глобальные массивы по поводу и без создавать. Если у тебя есть какая-то временная информация, которая используется только внутри тела конкретной функции, и ты для неё создаёшь глобальный массив - ты написал плохой код, который нерационально расходует память. И никак иначе.
    Вопрос 1: Почему-бы, не создать один большой массив в сегменте данных, скажем размером в 4096 ячеек и использовать его для форматирования различного содержательного текста?
    Да, стек так и так забрал себе память, но в таком случае пропадет необходимость ручного подсчета строки и пропадет возможная ситуация, когда массива не хватит;
    Данная реализация будет даже работать быстрее чем выделение памяти из стека (см. тесты в начале темы).

    Цитата Сообщение от DeimoS
    Ничего от этого не случится. Хорошо организованная таблица и правильно составленные запросы могут гарантировать то, что MySQL спокойно тысячи запросов в секунду прожуёт и не поперхнётся. А если ещё и серверное оборудование нормальное будет, то и до десятков тысяч эта цифра доходить будет.
    Вопрос 2: Как это "Хорошо организованная таблица", и "правильно составленные запросы"?
    Приведу пример, как я понимаю это: Таблица accounts, в ней находятся поля ID, Name, Money, Level, Exp, House, Business, Member, Rank... Во время Pay Day я обрабатываю игрока:
    1. new query[84+(-2+4)+(-2+5)+(-2+11)+(-2+8)+1];
    2. foreach(new i:Player) {
    3.  
    4. pInfo[i][Exp]++;
    5. if(pInfo[i][Exp] > 8) {
    6.  
    7. pInfo[i][Exp] = 0;
    8. pInfo[i][Level]++;
    9.  
    10. if(pInfo[i][Level] == 10) {
    11.  
    12. pInfo[i][Money] += 1000;
    13. format(query, sizeof(query), "UPDATE `accounts` SET `Level` = '%d', `Exp` = '%d', `Money` = '%d' WHERE `ID` = '%d'",
    14. pInfo[i][Level], pInfo[i][Exp], pInfo[i][Money], pInfo[i][ID]);
    15. }
    16. else
    17. format(query, sizeof(query), "UPDATE `accounts` SET `Level` = '%d', `Exp` = '%d' WHERE `ID` = '%d'",
    18. pInfo[i][Level], pInfo[i][Exp], pInfo[i][ID]);
    19. }
    20. else
    21. format(query, sizeof(query), "UPDATE `accounts` SET `Exp` = '%d' WHERE `ID` = '%d'",
    22. pInfo[i][Exp], pInfo[i][ID]);
    23.  
    24. mysql_tquery(id_DB, query);
    25. }

  5. #15
    Аватар для DeimoS
    Модератор?

    Статус
    Оффлайн
    Регистрация
    27.01.2014
    Адрес
    Восточный Мордор
    Сообщений
    5,588
    Репутация:
    1984 ±
    Цитата Сообщение от Shaolinka Посмотреть сообщение
    Создай булевую переменную для каждого игрока, при рестарте пройдись по всем игрокам, присвоив значение той булевой переменной на true. При выходе сверяй, был ли ли отключен игрок с помощью рестарта. Если да - сохраняй его данные.
    Да зачем это всё? Почему вы пытаетесь решать проблему, которой нет?


    Цитата Сообщение от punkochel Посмотреть сообщение
    Вопрос 1: Почему-бы, не создать один большой массив в сегменте данных, скажем размером в 4096 ячеек и использовать его для форматирования различного содержательного текста?
    Да, стек так и так забрал себе память, но в таком случае пропадет необходимость ручного подсчета строки и пропадет возможная ситуация, когда массива не хватит;
    Подсчёт строки занимает 10-30 секунд. При этом, глобальная переменная не только память лишнюю отжирает, но и увеличивает шанс допуска ошибки, которую ты уже будешь отыскивать гораздо дольше. Не говоря уже о том, что и читаемость кода ухудшается, ибо локальные переменные ты и назвать можешь информационно, и будет чётко видно где и какие данные начинают записываться. Если не забывать, что код, который ты пишешь, тебе ещё в будущем придётся поддерживать - станет очевидно, что сиюминутная польза глобального массива не стоит того, чтоб потом тратить кучу времени на попытки вспомнить, что же ты там писал пару месяцев назад. Ты либо сразу это поймёшь, либо когда напишешь достаточно объёмный скрипт. Но понимание этого придёт в любом случае. Благо люди не просто так со временем пришли к введению различных стандартов по синтаксису в разных ЯП. Это не ради забавы делается :)

    Цитата Сообщение от punkochel Посмотреть сообщение
    Данная реализация будет даже работать быстрее чем выделение памяти из стека (см. тесты в начале темы).
    Касаемо тестов:
    Во-первых, они у тебя некорректные.
    Во-вторых, как я и писал - разница будет только на уровне погрешности. На деле разницы по скорости не будет.


    Цитата Сообщение от punkochel Посмотреть сообщение
    Вопрос 2: Как это "Хорошо организованная таблица", и "правильно составленные запросы"?
    Это значит, что ты знаком с MySQL не на уровне уроков с Pawn-форумов, а конкретно изучил язык SQL, знаешь все его особенности и знаком с вариантами оптимизации, которые уже придумало сообщество (пример).
    Минимум, что нужно - это уметь создавать и работать с индексами, а так же знать все подноготные настроек таблицы, чтоб уметь её гибко настраивать.
    Связаться со мной в VK можно через личные сообщения этой группы
    Заказы не принимаю

    Широко известно, что идеи стоят 0.8333 цента каждая (исходя из рыночной цены 10 центов за дюжину).
    Великих идей полно, на них нет спроса.
    Воплощение идеи в законченную игру требует долгой работы,
    таланта, терпения и креативности, не говоря уж о затратах денег, времени и ресурсов.
    Предложить идею просто, воплотить – вот в чём проблема

    Steve Pavlina

  6. Пользователь сказал cпасибо:
    punkochel (05.11.2020)
  7. #16
    Аватар для punkochel
    Пользователь

    Статус
    Оффлайн
    Регистрация
    08.12.2018
    Адрес
    Россия
    Сообщений
    146
    Репутация:
    25 ±
    Спасибо, буду учиться!)

    Еще вопрос тогда:
    Как лучше хранить объемные тексты?

    После сегодняшней дискуссии я склоняюсь к этому:
    1. stock OtherFunction() {
    2.  
    3. static const fmt_dialog[] = !"Тут текст длиною в %i (1024) символа";
    4. new string[sizeof(fmt_dialog)*4 +1];
    5. strunpack(string, fmt_dialog);
    6. format(string, sizeof(string), string, 1024);
    7. printf("%s", string);
    8. }


    Или, все-таки не стоит хранить текст, который нужно форматировать, в упакованном виде?
    Последний раз редактировалось punkochel; 05.11.2020 в 19:50.

  8. #17
    Аватар для DeimoS
    Модератор?

    Статус
    Оффлайн
    Регистрация
    27.01.2014
    Адрес
    Восточный Мордор
    Сообщений
    5,588
    Репутация:
    1984 ±
    Цитата Сообщение от punkochel Посмотреть сообщение
    Спасибо, буду учиться!)

    Еще вопрос тогда:
    Как лучше хранить объемные тексты?

    После сегодняшней дискуссии я склоняюсь к этому:
    1. stock OtherFunction() {
    2.  
    3. static const fmt_dialog[] = !"Тут текст длиною в %i (1024) символа";
    4. new string[sizeof(fmt_dialog)*4 +1];
    5. strunpack(string, fmt_dialog);
    6. format(string, sizeof(string), string, 1024);
    7. printf("%s", string);
    8. }


    Или, все-таки не стоит хранить текст, который нужно форматировать, в упакованном виде?
    Особого смысла в этом нет. Ты лишь больше лишних действий производишь. Если бы были критичные проблемы с нехваткой памяти, тогда да - это имело бы смысл. Но сейчас ты пытаешься экономить память, которой и так в достатке, жертвуя при этом временем на обработку кода, которое как раз и не имеет больших излишков.



    Ну и да: всё же если ты хочешь нормальный тест, то стоило его сделать хотя бы таким:
    1. // Кол-во итераций в циклах.
    2. const PROFILER_ITERATIONS_MAJOR = 10_000;
    3. const PROFILER_ITERATIONS_MINOR = 1_000;
    4.  
    5.  
    6. new const code_snippets_names[2][] =
    7. {
    8. {"global_array"},
    9. {"local_array"}
    10. };
    11.  
    12. new global_array[100];
    13.  
    14. #define Prerequisites(); \
    15.   new local_array[100];
    16.  
    17.  
    18. #define CodeSnippet0(); \
    19.   if(global_array[50] == 10)\
    20.   global_array[50] = 0;\
    21.   else\
    22.   global_array[50] = 10;
    23.  
    24.  
    25. #define CodeSnippet1(); \
    26.   if(local_array[50] == 10)\
    27.   local_array[50] = 0;\
    28.   else\
    29.   local_array[50] = 10;

    Ибо в твоём варианте у локальных переменных будет больше действий выполняться, чем у глобальных.
    Ну и сделай сразу штук 10 тестов, чтоб убедиться, что быстрее будут то локальные, то глобальные переменные (то бишь, всё на уровне погрешности)
    Связаться со мной в VK можно через личные сообщения этой группы
    Заказы не принимаю

    Широко известно, что идеи стоят 0.8333 цента каждая (исходя из рыночной цены 10 центов за дюжину).
    Великих идей полно, на них нет спроса.
    Воплощение идеи в законченную игру требует долгой работы,
    таланта, терпения и креативности, не говоря уж о затратах денег, времени и ресурсов.
    Предложить идею просто, воплотить – вот в чём проблема

    Steve Pavlina

  9. #18
    Аватар для punkochel
    Пользователь

    Статус
    Оффлайн
    Регистрация
    08.12.2018
    Адрес
    Россия
    Сообщений
    146
    Репутация:
    25 ±
    Тогда я попробую подвести итог темы:

    Не стоит использовать память из сегмента данных для реализации локальных действий, а именно:
    - Если стоит отформатировать и вывести текст, то лучше использовать локальный массив (стек), так как память в стеке выделена по умолчанию, и нет смысла создавать ему подобные реализации, тем самым впустую расходовать память;

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


    Так-же не стоит хранить содержательные тексты в упакованном виде, ибо при необходимости форматирования данного текста, предварительно будет использована функция strunpack, которая в свою очередь повлияет на производительность.

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

  10. #19
    Аватар для DeimoS
    Модератор?

    Статус
    Оффлайн
    Регистрация
    27.01.2014
    Адрес
    Восточный Мордор
    Сообщений
    5,588
    Репутация:
    1984 ±
    Цитата Сообщение от punkochel Посмотреть сообщение
    Не стоит использовать память из сегмента данных для реализации локальных действий, а именно:
    - Если стоит отформатировать и вывести текст, то лучше использовать локальный массив (стек), так как память в стеке выделена по умолчанию, и нет смысла создавать ему подобные реализации, тем самым впустую расходовать память;

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

    Сегодня сервера работают на довольно мощном оборудовании, и экономия памяти сейчас не является первоочередной задачей, при этом расходовать её попусту тоже не желательно, лучше отдать предпочтение производительности.
    И да, и нет. Ещё раз обращу внимание на фактор читаемости кода и на фактор устойчивости к ошибкам.

    С глобальной переменной у тебя все места, где ты записываешь какой-то текст (а во многих говномодах и не только текст в эти массивы пихают), все упоминания массива (его название) не будут говорить ни о текущем содержимом массива, ни о предназначении этой информации. Если у тебя появится нужда подредактировать код - тебе придётся его читать от самого начала, тратя время на доскональное изучение. В случае же с локальными массивами и переменными, ты можешь дать им нормальные имена, которые будут говорить о их предназначении. Тем самым, когда ты в следующий раз решишь прочесть код, тебе достаточно будет взглянуть на название переменной, чтоб понять то, какой код ты перед собой видишь и что он означает. Это касаемо читаемости.

    Касаемо устойчивости к ошибкам: используя один общий глобальный массив, ты самостоятельно убиваешь одну из способностей компилятора, которая помогает тебе отыскать твои ошибки ещё на стадии компиляции - ошибку с указанием неправильной переменной.
    Приведу пример, который уже несколько раз описывал на форуме:
    Представим, что у тебя есть глобальный массив "global_string". Ты используешь его при форматировании сообщений и у тебя, казалось бы, жизнь удалась. Ты просто можешь копировать уже написанный ранее код форматирования какого-то сообщения, изменить в нём текст и не тратить время на написание "format" и "SendClientMessage" со всем вытекающим. Но тут у тебя возникла ситуация, при которой ты не можешь использовать свой массив: например, у тебя есть ветвление условий, в котором ты форматируешь разный текст, и чтоб там не дублировать одинаковый SendClientMessage, ты просто вынес его за тело условий, а-ля:
    1. switch(variable)
    2. {
    3. case 0:
    4. {
    5. // Тут какой-то код
    6. format(global_string, sizeof(global_string), "...");
    7. }
    8. case 2:
    9. {
    10. // Тут какой-то код
    11. format(global_string, sizeof(global_string), "...");
    12. }
    13. case 3:
    14. {
    15. // Тут какой-то код
    16. format(global_string, sizeof(global_string), "...");
    17. }
    18. }
    19. SendClientMessage(playerid, -1, global_string);


    И тут тебе, например, понадобилось ещё и запросы форматировать к БД, для которых ты обычно так же global_string использовал. Ты решаешь создать новую переменную и, чтоб сэкономить время, просто копируешь форматирование запроса с другого участка кода, чуть переписав его. Напомню, что ты "global_string" используешь и для отправки запросов обычно (ибо так обычно в паблик модах и делают). В итоге получается следующее:
    1. new query_string[...];
    2. switch(variable)
    3. {
    4. case 0:
    5. {
    6. // Тут какой-то код
    7. format(global_string, sizeof(global_string), "...");
    8. format(query_string, sizeof(query_string), "запрос");
    9. }
    10. case 2:
    11. {
    12. // Тут какой-то код
    13. format(global_string, sizeof(global_string), "...");
    14. format(query_string, sizeof(query_string), "запрос");
    15. }
    16. case 3:
    17. {
    18. // Тут какой-то код
    19. format(global_string, sizeof(global_string), "...");
    20. format(query_string, sizeof(query_string), "запрос");
    21. }
    22. }
    23. SendClientMessage(playerid, -1, global_string);
    24. mysql_tquery(mysql_connection_ID, global_string, "", "");

    Но вот незадача: в format ты название массива сменил, а вот в mysql_tquery забыл. Но, компилируя, ты никаких ошибок не получишь, ибо, с точки зрения компилятора, тут никаких синтаксических ошибок нет: все переменные существуют.

    Приведённый пример, конечно, притянут за уши, ибо я не смог вспомнить реальные примеры, которые встречал неоднократно за всё время выполнение заказов по Pawn, но общая суть тут передаётся. Причину ошибки, если ты раньше ничего подобного не встречал, ты можешь искать и минуту, и десять минут, и час. А если бы ты взял за привычку работать с локальными массивами и давал бы им адекватные названия, то, при копировании кода из одной системы в другую, компилятор бы сообщил тебе об ошибке, так как в этом блоке кода такого названия бы не было. Собственно, вот так ты и усложняешь себе жизнь, повышая риск допущения ошибок.
    Это, собственно, тема из той же оперы, что и присвоение нормальных названий переменным/функциям, использование строгих правил синтаксиса или же, например, правила, при котором тело функции не должно быть длиннее 60 строк. Всё это, с первого взгляда, кажется мелочью, но на деле, когда ты начинаешь всего этого придерживаться и чётко структурировать свой код, твоя производительность повышается многократно, так как ты меньше времени тратишь на исправление ошибок (ибо делаешь их меньше) и меньше времени тратишь на изучение уже написанного кода, так как он не представляет из себя хаос и разруху, которую можно увидеть в любом паблик-моде.
    Связаться со мной в VK можно через личные сообщения этой группы
    Заказы не принимаю

    Широко известно, что идеи стоят 0.8333 цента каждая (исходя из рыночной цены 10 центов за дюжину).
    Великих идей полно, на них нет спроса.
    Воплощение идеи в законченную игру требует долгой работы,
    таланта, терпения и креативности, не говоря уж о затратах денег, времени и ресурсов.
    Предложить идею просто, воплотить – вот в чём проблема

    Steve Pavlina

  11. Пользователь сказал cпасибо:
    punkochel (06.11.2020)
  12. #20
    Аватар для Shaolinka
    Пользователь

    Статус
    Оффлайн
    Регистрация
    19.01.2020
    Сообщений
    69
    Репутация:
    8 ±
    В паблик модах забывают почистить глобальный перед началом использования, что приводит к огромнейшим проблемам. Или выделяют овер дофига ячеек по причине: «шобы была на патом», потом же в силу вступает #pragma dynamic.
    И как гаварица:

  13. Пользователь сказал cпасибо:
    Mexanizm (05.11.2020)
 

 
Страница 2 из 4 ПерваяПервая 1 2 3 4 ПоследняяПоследняя

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Ваши права

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