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

    Статус
    Оффлайн
    Регистрация
    07.01.2020
    Сообщений
    9
    Репутация:
    0 ±

    Оптимизация switch

    Здравствуйте, я не очень силен в оптимизации, подскажите пожалуйста возможно ли как-то данный код (в спойлере) упаковать компактнее и более оптимизировано? пробывал на if`ax разницы в скорости не обнаружил. Ах да еще и компиляция увеличилась где-то +- на 20 секунд. с 2-3 секунд.

     Спойлер
    PHP код:
        switch(pInfo[playerid][pKills)
        {
            case 
    0..199:
                
    newlevel 0;
            case 
    200..399:
                
    newlevel 1;
            case 
    400..599:
                
    newlevel 2;
            case 
    600..799:
                
    newlevel 3;
            case 
    800..999:
                
    newlevel 4;
            case 
    1000..1499:
                
    newlevel 5;
            case 
    1500..1999:
                
    newlevel 6;
            case 
    2000..2499:
                
    newlevel 7;
            case 
    2500..2999:
                
    newlevel 8;
            case 
    3000..3499:
                
    newlevel 9;
            case 
    3500..3999:
                
    newlevel 10;
            case 
    4000..4999:
                
    newlevel 11;
            case 
    5000..5999:
                
    newlevel 12;
            case 
    6000..11999:
                
    newlevel 13;
            case 
    12000..14999:
                
    newlevel 14;
            case 
    15000..24999:
                
    newlevel 15;
            case 
    25000..50000:
                
    newlevel 16;
        } 

  2. #2
    Аватар для SteveStage
    Пользователь

    Статус
    Оффлайн
    Регистрация
    05.10.2019
    Адрес
    Планета Земля
    Сообщений
    318
    Репутация:
    7 ±
    Видите ли, в вашем случае лучше использовать if, т.к. switch перебирает все значения в диапазоне, а на if можно просто сравнить с самым маленьким и самым большим.
    Так будет лучше:

    1. if(pInfo[playerid][pKills] >= 0 && pInfo[playerid][pKills] <= 199) newlevel = 0;
    2. else if(pInfo[playerid][pKills] >= 200 && pInfo[playerid][pKills] <= 399) newlevel = 1;
    3. else if(pInfo[playerid][pKills] >= 400 && pInfo[playerid][pKills] <= 599) newlevel = 2;
    4. else if(pInfo[playerid][pKills] >= 600 && pInfo[playerid][pKills] <= 799) newlevel = 3;
    5. else if(pInfo[playerid][pKills] >= 800 && pInfo[playerid][pKills] <= 999) newlevel = 4;
    6. else if(pInfo[playerid][pKills] >= 1000 && pInfo[playerid][pKills] <= 1499) newlevel = 5;
    7. else if(pInfo[playerid][pKills] >= 1500 && pInfo[playerid][pKills] <= 1999) newlevel = 6;
    8. else if(pInfo[playerid][pKills] >= 2000 && pInfo[playerid][pKills] <= 2499) newlevel = 7;
    9. else if(pInfo[playerid][pKills] >= 2500 && pInfo[playerid][pKills] <= 2999) newlevel = 8;
    10. else if(pInfo[playerid][pKills] >= 3000 && pInfo[playerid][pKills] <= 3499) newlevel = 9;
    11. else if(pInfo[playerid][pKills] >= 3500 && pInfo[playerid][pKills] <= 3999) newlevel = 10;
    12. else if(pInfo[playerid][pKills] >= 4000 && pInfo[playerid][pKills] <= 4999) newlevel = 11;
    13. else if(pInfo[playerid][pKills] >= 5000 && pInfo[playerid][pKills] <= 5999) newlevel = 12;
    14. else if(pInfo[playerid][pKills] >= 6000 && pInfo[playerid][pKills] <= 11999) newlevel = 13;
    15. else if(pInfo[playerid][pKills] >= 12000 && pInfo[playerid][pKills] <= 14999) newlevel = 14;
    16. else if(pInfo[playerid][pKills] >= 15000 && pInfo[playerid][pKills] <= 24999) newlevel = 15;
    17. else if(pInfo[playerid][pKills] >= 25000 && pInfo[playerid][pKills] <= 50000) newlevel = 16;


    Да и к слову, в вашем варианте с switch была допущена ошибка

    switch(pInfo[playerid][pKills)

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

    Статус
    Оффлайн
    Регистрация
    04.01.2015
    Адрес
    Гомель, Беларусь
    Сообщений
    547
    Репутация:
    158 ±
    Цитата Сообщение от Steve_Stage Посмотреть сообщение
    Видите ли, в вашем случае лучше использовать if, т.к. switch перебирает все значения в диапазоне, а на if можно просто сравнить с самым маленьким и самым большим.
    Так будет лучше:

    1. if(pInfo[playerid][pKills] >= 0 && pInfo[playerid][pKills] <= 199) newlevel = 0;
    2. else if(pInfo[playerid][pKills] >= 200 && pInfo[playerid][pKills] <= 399) newlevel = 1;
    3. else if(pInfo[playerid][pKills] >= 400 && pInfo[playerid][pKills] <= 599) newlevel = 2;
    4. else if(pInfo[playerid][pKills] >= 600 && pInfo[playerid][pKills] <= 799) newlevel = 3;
    5. else if(pInfo[playerid][pKills] >= 800 && pInfo[playerid][pKills] <= 999) newlevel = 4;
    6. else if(pInfo[playerid][pKills] >= 1000 && pInfo[playerid][pKills] <= 1499) newlevel = 5;
    7. else if(pInfo[playerid][pKills] >= 1500 && pInfo[playerid][pKills] <= 1999) newlevel = 6;
    8. else if(pInfo[playerid][pKills] >= 2000 && pInfo[playerid][pKills] <= 2499) newlevel = 7;
    9. else if(pInfo[playerid][pKills] >= 2500 && pInfo[playerid][pKills] <= 2999) newlevel = 8;
    10. else if(pInfo[playerid][pKills] >= 3000 && pInfo[playerid][pKills] <= 3499) newlevel = 9;
    11. else if(pInfo[playerid][pKills] >= 3500 && pInfo[playerid][pKills] <= 3999) newlevel = 10;
    12. else if(pInfo[playerid][pKills] >= 4000 && pInfo[playerid][pKills] <= 4999) newlevel = 11;
    13. else if(pInfo[playerid][pKills] >= 5000 && pInfo[playerid][pKills] <= 5999) newlevel = 12;
    14. else if(pInfo[playerid][pKills] >= 6000 && pInfo[playerid][pKills] <= 11999) newlevel = 13;
    15. else if(pInfo[playerid][pKills] >= 12000 && pInfo[playerid][pKills] <= 14999) newlevel = 14;
    16. else if(pInfo[playerid][pKills] >= 15000 && pInfo[playerid][pKills] <= 24999) newlevel = 15;
    17. else if(pInfo[playerid][pKills] >= 25000 && pInfo[playerid][pKills] <= 50000) newlevel = 16;


    Да и к слову, в вашем варианте с switch была допущена ошибка
    От
    PHP код:
    && pInfo[playerid][pKills] <= 199 

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

    PHP код:
    if(pInfo[playerid][pKills] >= 25000 && pInfo[playerid][pKills] <= 50000newlevel 16;
    else if(
    pInfo[playerid][pKills] >= 15000newlevel 15;
    else if(
    pInfo[playerid][pKills] >= 12000newlevel 14;
    else if(
    pInfo[playerid][pKills] >= 6000newlevel 13;
    else if(
    pInfo[playerid][pKills] >= 5000newlevel 12;
    else if(
    pInfo[playerid][pKills] >= 4000newlevel 11;
    else if(
    pInfo[playerid][pKills] >= 3500newlevel 10;
    else if(
    pInfo[playerid][pKills] >= 3000newlevel 9;
    else if(
    pInfo[playerid][pKills] >= 2500newlevel 8;
    else if(
    pInfo[playerid][pKills] >= 2000newlevel 7;
    else if(
    pInfo[playerid][pKills] >= 1500newlevel 6;
    else if(
    pInfo[playerid][pKills] >= 1000newlevel 5;
    else if(
    pInfo[playerid][pKills] >= 800newlevel 4;
    else if(
    pInfo[playerid][pKills] >= 600newlevel 3;
    else if(
    pInfo[playerid][pKills] >= 400newlevel 2;
    else if(
    pInfo[playerid][pKills] >= 200newlevel 1;
    else if(
    pInfo[playerid][pKills] >= 0newlevel 0;

    //Возможные дыры, не учитываемые в изначальной логике условий и в этой: newlevel ничему не присвоится при значениях pInfo[playerid][pKills] ниже нуля и больше 50000 


    Хотя самым эффективным вариантом было бы приведение всего этого к единой формуле вместо большого количества условий.
    Последний раз редактировалось Nexius_Tailer; 10.01.2020 в 01:31.
    Не хотите постоянно проверять обновления моих скриптов?
    Подключите его последним, после всех остальных
    Nexius's Update Checker

  4. Пользователь сказал cпасибо:
    R1KO (10.01.2020)
  5. #4
    Аватар для R1KO
    Пользователь

    Статус
    Оффлайн
    Регистрация
    07.01.2020
    Сообщений
    9
    Репутация:
    0 ±
    Цитата Сообщение от Nexius_Tailer Посмотреть сообщение
    От
    PHP код:
    && pInfo[playerid][pKills] <= 199 

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

    PHP код:
    if(pInfo[playerid][pKills] >= 25000 && pInfo[playerid][pKills] <= 50000newlevel 16;
    else if(
    pInfo[playerid][pKills] >= 15000newlevel 15;
    else if(
    pInfo[playerid][pKills] >= 12000newlevel 14;
    else if(
    pInfo[playerid][pKills] >= 6000newlevel 13;
    else if(
    pInfo[playerid][pKills] >= 5000newlevel 12;
    else if(
    pInfo[playerid][pKills] >= 4000newlevel 11;
    else if(
    pInfo[playerid][pKills] >= 3500newlevel 10;
    else if(
    pInfo[playerid][pKills] >= 3000newlevel 9;
    else if(
    pInfo[playerid][pKills] >= 2500newlevel 8;
    else if(
    pInfo[playerid][pKills] >= 2000newlevel 7;
    else if(
    pInfo[playerid][pKills] >= 1500newlevel 6;
    else if(
    pInfo[playerid][pKills] >= 1000newlevel 5;
    else if(
    pInfo[playerid][pKills] >= 800newlevel 4;
    else if(
    pInfo[playerid][pKills] >= 600newlevel 3;
    else if(
    pInfo[playerid][pKills] >= 400newlevel 2;
    else if(
    pInfo[playerid][pKills] >= 200newlevel 1;
    else if(
    pInfo[playerid][pKills] >= 0newlevel 0;

    //Возможные дыры, не учитываемые в изначальной логике условий и в этой: newlevel ничему не присвоится при значениях pInfo[playerid][pKills] ниже нуля и больше 50000 


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

  6. #5
    Аватар для Nexius_Tailer
    Пользователь

    Статус
    Оффлайн
    Регистрация
    04.01.2015
    Адрес
    Гомель, Беларусь
    Сообщений
    547
    Репутация:
    158 ±
    Цитата Сообщение от R1KO Посмотреть сообщение
    к единой формуле это было бы замечательно, но вот только как это условие составить?
    При текущих цифрах нет прямых прогрессий (будь то арифметической или геометрической). Если есть желание менять значения с киллами в угоду построения простой формулы, то можно провернуть как раз через эти арифметические или геометрические прогрессии (погугли). В первом случае кол-во киллов для нового lvl'а будет равно старому lvl'у + некое постоянное число (киллов), являющееся разницей между двумя лвлами. В геометрической прогрессии похоже, но кол-во киллов в каждом новом лвле уже будет во сколько-то раз большим предыдущего (умножение), а не на сколько-то (прибавление). Если желания менять сами значения ради такой оптимизации нет, то вполне можно оставить и как есть, ну или попробовать ещё сделать с использованием массива + цикл, хотя там в скорости точно прироста ожидать не стоит (максимум - в удобстве добавления новых уровней).
    Последний раз редактировалось Nexius_Tailer; 10.01.2020 в 03:02.
    Не хотите постоянно проверять обновления моих скриптов?
    Подключите его последним, после всех остальных
    Nexius's Update Checker

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

    Статус
    Оффлайн
    Регистрация
    07.01.2020
    Сообщений
    9
    Репутация:
    0 ±
    Цитата Сообщение от Nexius_Tailer Посмотреть сообщение
    При текущих цифрах нет прямых прогрессий (будь то арифметической или геометрической). Если есть желание менять значения с киллами в угоду построения простой формулы, то можно провернуть как раз через эти арифметические или геометрические прогрессии (погугли). В первом случае кол-во киллов для нового lvl'а будет равно старому lvl'у + некое постоянное число (киллов), являющееся разницей между двумя лвлами. В геометрической прогрессии похоже, но кол-во киллов в каждом новом лвле уже будет во сколько-то раз большим предыдущего (умножение), а не на сколько-то (прибавление). Если желания менять сами значения ради такой оптимизации нет, то вполне можно оставить и как есть, ну или попробовать ещё сделать с использованием массива + цикл, хотя там в скорости точно прироста ожидать не стоит (максимум - в удобстве добавления новых уровней).
    Спасибо сделаю подобное как система уровней на рп серверах.

 

 

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

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

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

Ваши права

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