Добро пожаловать на Pro Pawn - Портал о PAWN-скриптинге.
Показано с 1 по 2 из 2
  1. #1
    Аватар для ALIT13
    Пользователь

    Статус
    Оффлайн
    Регистрация
    24.05.2014
    Сообщений
    346
    Репутация:
    2 ±

    Вопрос по Stack/heap size:

    Хочу узнать почему так, если я задаю общую переменную например на 1000
    new string[1000];
    у меня стейк
    Stack/heap size: 16384 bytes; estimated max. usage=2849 cells (8200 bytes)
    А когда я под каждую подсчитал у меня выходит
    Stack/heap size: 16384 bytes; estimated max. usage=2249 cells (8996 bytes)

    Как вообще лучше делать для экономия Так

    Общий на все
    new string[1000];

    PHP код:
                    format(string,sizeof(string),"INSERT INTO `"table_bizz"`(`bID`, `bOwned`, `bOwner`,`bName`, `bEnterX`, `bEnterY`, `bEnterZ`, `bExitX`, `bExitY`, `bExitZ`, `bPrice`, `bTakings`, `bInt`, `bBizz`, `bSklad`, `bBuyprice`, `bPriceEnter`, `bClass`,`bLock`,`bBalance`) VALUES ('%i','%i','%s','%s','%f','%f','%f','%f','%f','%f','%i','%i','%i','%i','%i','%i','%i','%i','%i','%i')",
                    
    BizzInfo[TOTALBIZZ][bID],BizzInfo[TOTALBIZZ][bOwned],BizzInfo[TOTALBIZZ][bOwner],BizzInfo[TOTALBIZZ][bName],BizzInfo[TOTALBIZZ][bEnterX],BizzInfo[TOTALBIZZ][bEnterY],BizzInfo[TOTALBIZZ][bEnterZ],BizzInfo[TOTALBIZZ][bExitX],BizzInfo[TOTALBIZZ][bExitY],BizzInfo[TOTALBIZZ][bExitZ],BizzInfo[TOTALBIZZ][bPrice],BizzInfo[TOTALBIZZ][bTakings],BizzInfo[TOTALBIZZ][bInt],BizzInfo[TOTALBIZZ][bBizz],BizzInfo[TOTALBIZZ][bSklad],
                    
    BizzInfo[TOTALBIZZ][bBuyprice],BizzInfo[TOTALBIZZ][bPriceEnter],BizzInfo[TOTALBIZZ][bClass],BizzInfo[TOTALBIZZ][bLock],BizzInfo[TOTALBIZZ][bBalance]);
                    
    mysql_tquery(con_bdstring"",""); 
    Или отдельно
    PHP код:
        new str_biz[500];
                    
    format(str_biz,sizeof(str_biz),"INSERT INTO `"table_bizz"`(`bID`, `bOwned`, `bOwner`,`bName`, `bEnterX`, `bEnterY`, `bEnterZ`, `bExitX`, `bExitY`, `bExitZ`, `bPrice`, `bTakings`, `bInt`, `bBizz`, `bSklad`, `bBuyprice`, `bPriceEnter`, `bClass`,`bLock`,`bBalance`) VALUES ('%i','%i','%s','%s','%f','%f','%f','%f','%f','%f','%i','%i','%i','%i','%i','%i','%i','%i','%i','%i')",
                    
    BizzInfo[TOTALBIZZ][bID],BizzInfo[TOTALBIZZ][bOwned],BizzInfo[TOTALBIZZ][bOwner],BizzInfo[TOTALBIZZ][bName],BizzInfo[TOTALBIZZ][bEnterX],BizzInfo[TOTALBIZZ][bEnterY],BizzInfo[TOTALBIZZ][bEnterZ],BizzInfo[TOTALBIZZ][bExitX],BizzInfo[TOTALBIZZ][bExitY],BizzInfo[TOTALBIZZ][bExitZ],BizzInfo[TOTALBIZZ][bPrice],BizzInfo[TOTALBIZZ][bTakings],BizzInfo[TOTALBIZZ][bInt],BizzInfo[TOTALBIZZ][bBizz],BizzInfo[TOTALBIZZ][bSklad],
                    
    BizzInfo[TOTALBIZZ][bBuyprice],BizzInfo[TOTALBIZZ][bPriceEnter],BizzInfo[TOTALBIZZ][bClass],BizzInfo[TOTALBIZZ][bLock],BizzInfo[TOTALBIZZ][bBalance]);
                    
    mysql_tquery(con_bdstr_biz"",""); 

    Сделал ровный подсчёт
    PHP код:
                static const biz[] = "INSERT INTO `"table_bizz"`(`bID`, `bOwned`, `bOwner`,`bName`, `bEnterX`, `bEnterY`, `bEnterZ`, `bExitX`, `bExitY`, `bExitZ`, `bPrice`, `bTakings`, `bInt`, `bBizz`, `bSklad`, `bBuyprice`, `bPriceEnter`, `bClass`,`bLock`,`bBalance`) VALUES ('%i','%i','%s','%s','%f','%f','%f','%f','%f','%f','%i','%i','%i','%i','%i','%i','%i','%i','%i','%i')";
                    new 
    str_biz[sizeof(biz) + 250 MAX_PLAYER_NAME 40];
                    
    format(str_bizsizeof(str_biz), bizBizzInfo[TOTALBIZZ][bID],BizzInfo[TOTALBIZZ][bOwned],BizzInfo[TOTALBIZZ][bOwner],BizzInfo[TOTALBIZZ][bName],BizzInfo[TOTALBIZZ][bEnterX],BizzInfo[TOTALBIZZ][bEnterY],BizzInfo[TOTALBIZZ][bEnterZ],BizzInfo[TOTALBIZZ][bExitX],BizzInfo[TOTALBIZZ][bExitY],BizzInfo[TOTALBIZZ][bExitZ],BizzInfo[TOTALBIZZ][bPrice],BizzInfo[TOTALBIZZ][bTakings],BizzInfo[TOTALBIZZ][bInt],BizzInfo[TOTALBIZZ][bBizz],BizzInfo[TOTALBIZZ][bSklad],
                    
    BizzInfo[TOTALBIZZ][bBuyprice],BizzInfo[TOTALBIZZ][bPriceEnter],BizzInfo[TOTALBIZZ][bClass],BizzInfo[TOTALBIZZ][bLock],BizzInfo[TOTALBIZZ][bBalance]);
                    
    mysql_tquery(con_bdstr_biz"",""); 

    Стейк показывает вообще
    Stack/heap size: 16384 bytes; estimated max. usage=2315 cells (9260 bytes)
    Последний раз редактировалось ALIT13; 05.01.2019 в 13:00.

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

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

    Вообще кто вам сказал, что нужно экономить стэк? Это, грубо говоря, обычная глобальная переменная (массив), только для неё добавлена возможность работать с конкретными ячейками этого "массива" как с отдельными переменными и автоматизирована чистка уже не нужных ячеек. Вам наоборот пытаются упростить жизнь, а вы, вместо этого, создаёте аналог стэка в виде глобального массива, только то, что в стэке делается автоматически, вы перекладываете на себя и сидите довольные...




    По примерам:

    В первом случае ты ничего не экономишь, а наоборот расходуешь дополнительные 1000 ячеек сегмента данных. От того, что ты не будешь использовать те 4096 ячеек стэка, которые выделяются по умолчанию, а создашь свою переменную, эти самые 4096 "зарезервированных" стэком ячеек не исчезнут и всё так же будут висеть в памяти (просто в них не будет полезной информации), а ты дополнительно выделишь ещё 1000 ячеек. В итоге, вместо 4096 ячеек, ты уже будешь использовать 5096, из которых большая часть не будет никак использоваться (тот стэк, который ты "экономишь").

    Второй и третий пример уже близки к истине, только стоит ещё нормально подсчитать размер строки и входящих в неё данных, а не абы как писать этот самый размер. Правильный подсчёт размера - это именно то, что подразумевается под "экономией" памяти (скорее, рациональное использование памяти), а не ваши глобальные переменные, которые вы пихаете по поводу и без.
    А стэк можно и нужно использовать. И если вдруг вы превысили стандартные 4096 ячеек, то не стесняйтесь увеличивать размер стэка, а не лепите дополнительные глобальные переменные, которые, в большинстве случаев, в несколько раз раздувают сегмент данных, в отличии от того самого увеличения стэка. Подробнее об этом ниже.




    Когда компилятор подсчитывает количество использованного стэка, он не просто суммирует все локальные переменные, а делает это по определённым правилам, которые нужно знать и которые помогут действительно рационально использовать стэк. Вот, пожалуй, самое основное:

    Важно помнить, что локальные переменные удаляются из памяти в момент, когда завершается обработка того блока кода, в котором они объявлены.
    Например:
    PHP код:
    main()
    {
        new 
    array1[500];
        
    #pragma unused array1
        
    new array2[500];
        
    #pragma unused array2

    В этом случае в стэке будет зарезервировано +1000 ячеек, так как мы объявили 2 массива по 500 ячеек в одном блоке кода.
    Но стоит нам просто поместить массивы в разные блоки кода:
    PHP код:
    main()
    {
        {
            new 
    array1[500];
            
    #pragma unused array1
        
    }
        {
            new 
    array2[500];
            
    #pragma unused array2
        
    }

    И выделено будет уже 500 ячеек, а не 1000.
    То же самое происходит и с отдельными коллбэками: если у нас есть два коллбэка, в одном из которых создаётся массив в 500 ячеек, а во втором - 1000 ячеек, то размер стэка будет равен 1000, а не 1500. Как раз потому, что когда, допустим, первый коллбэк обработается, все данные из стэка будут удалены и те ячейки, которые совсем недавно использовались под массив с 500 ячейками, будут повторно использоваться под второй коллбэк и массив с 1000 ячейками.

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




    Теперь вернёмся к увеличению стэка.
    Представим, что размер нашего стэка равен 2000 ячеек, а так же есть скрипт, который потребляет 1500 ячеек. У нас появилась нужда дописать скрипт, добавив в него информацию, которой нужно ещё 1000 ячеек для хранения. Если мы запишем их в стэк, то получим переполнение стэка (будет потребляться 2500 стэка, хотя выделено всего 2000).
    Мамкины оптимизаторы посоветуют вам создать глобальный массив, равный 1000 ячейкам, и записать данные в него, а не увеличивать размер стэка (ведь стэк увеличивают лишь нубы!!1!). Но что получится на самом деле?

    Если вы создадите глобальный массив, то вы зарезервируете дополнительные 1000 ячеек из сегмента данных, оставив свободными 500 ячеек стэка (но они, при этом, всё так же будут занимать сегмент данных, а не исчезнут волшебным образом). Соответственно, ваш скрипт уже будет "потреблять" 3000 ячеек сегмента данных (2000 под стэк и 1000 под массив).
    Но так же вы можете увеличить стек и тут потребуется всего 500 дополнительных ячеек, чтоб уместить новую информацию, так как у нас уже есть 500 свободных ячеек в стеке. Думаю, понятно, что, в случае увеличения стэка, экономия памяти очевидна. Поэтому не стоит слушать мамкиных оптимизаторов и бояться увеличивать стэк.
    Стандартный размер (4096 ячеек) особо ничем не обусловлен и увеличение этого размера никак не скажется негативно на вашем сервере (скорее, наоборот, вы сэкономите памяти, как выяснилось выше). Главное понимать как работает память и выделять её ровно столько, сколько требуется. Это будет гораздо полезнее, чем все эти ваши танцы с глобальными массивами.
    Последний раз редактировалось DeimoS; 17.12.2019 в 21:31.
    Связаться со мной в VK можно через личные сообщения этой группы
    Заказы не принимаю

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

    Steve Pavlina

  3. 5 пользователя(ей) сказали cпасибо:
    Aurelius (27.02.2020) DmitriyVasilev (30.03.2019) geneff (20.01.2019) Pa4enka (17.01.2019) whale (17.01.2019)
 

 

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

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

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

Ваши права

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