Почему статическая инициализация значительно улучшает время выполнения по сравнению с инициализацией конструктора в C ++C++

Программы на C++. Форум разработчиков
Ответить Пред. темаСлед. тема
Anonymous
 Почему статическая инициализация значительно улучшает время выполнения по сравнению с инициализацией конструктора в C ++

Сообщение Anonymous »

Я реализовал две версии решения для следующей задачи LeetCode:
🔗 максимальные и минимальные суммы при последующих размерах k < br/>
Учитывая целочисленные массивы nums и положительное целое число k , верните сумму максимальных и минимальных элементов всех последствий Nums с максимума k элементы. Поскольку результат может быть большим, вернуть It Modulo 10^9 + 7 .

Обе реализации используют предварительно вычисленные факториалы и модульные образы для эффективного вычисления комбинаций. Однако один инициализирует эти значения в конструкторе класса , в то время как другой использует статическую инициализацию в функции лямбда.
💡 Удивительная разница в производительности на LeetCode
  • code 1 (инициализация на основе конструктора) занимает ~ 2000 мс.
  • код 2 (статическая инициализация) занимает только ~ 30 мс (~ 66x ускорение). < /li>
    код 1: инициализация на основе конструктора (~ 2000 мс) < /strong> < /h3>

    Код: Выделить всё

    class Solution {
    private:
    const int mod = 1e9 + 7;
    const int MX = 1e5 + 1;
    vector F, REC_F;
    
    public:
    Solution() {
    F.resize(MX);
    REC_F.resize(MX);
    F[0] = 1;
    for (int i = 1; i < MX; ++i) {
    F[i] = F[i - 1] * i % mod;
    }
    REC_F[MX - 1] = power(F[MX - 1], mod - 2);
    for (int i = MX - 2; i >= 0; --i) {
    REC_F[i] = REC_F[i + 1] * (i + 1) % mod;
    }
    }
    
    int minMaxSums(vector& nums, int k) {
    sort(nums.begin(), nums.end());
    int n = nums.size();
    long long ans = 0, s = 1;
    
    for (int i = 0; i < n; ++i) {
    ans = (ans + s * (nums[i] + nums[n - 1 - i])) % mod;
    s = (2 * s - comb(i, k - 1) + mod) % mod;
    }
    return ans;
    }
    
    long long comb(int n, int m) {
    return n < m ? 0 : F[n] * REC_F[m] % mod * REC_F[n - m] % mod;
    }
    
    long long power(long long x, int n) {
    long long ans = 1;
    for (; n > 0; n /= 2) {
    if (n % 2) ans = (ans * x) % mod;
    x = (x * x) % mod;
    }
    return ans;
    }
    };
    
    
    код 2: статическая инициализация (~ 30 мс, ~ 66x быстрее) [/b]

    Код: Выделить всё

    const int mod = 1'000'000'007;
    const int MX = 100'000;
    long long F[MX]; // Factorial
    long long REC_F[MX]; // Inverse Factorial
    
    long long power(long long x, int n) {
    long long ans = 1;
    for (; n > 0; n /= 2) {
    if (n & 1) ans = (ans * x) % mod;
    x = (x * x) % mod;
    }
    return ans;
    }
    
    auto init = [] {
    F[0] = 1;
    for (int i = 1; i < MX; ++i) {
    F[i] = F[i - 1] * i % mod;
    }
    REC_F[MX - 1] = power(F[MX - 1], mod - 2);
    for (int i = MX - 2; i >= 0; --i) {
    REC_F[i] = REC_F[i + 1] * (i + 1) % mod;
    }
    return 0;
    }();
    
    class Solution {
    public:
    int minMaxSums(vector& nums, int k) {
    sort(nums.begin(), nums.end());
    int n = nums.size();
    long long ans = 0, s = 1;
    
    for (int i = 0; i < n; ++i) {
    ans = (ans + s * (nums[i] + nums[n - 1 - i])) % mod;
    s = (2 * s - comb(i, k - 1) + mod) % mod;
    }
    return ans;
    }
    
    long long comb(int n, int m) {
    return n < m ? 0 : F[n] * REC_F[m] % mod * REC_F[n - m] % mod;
    }
    };
    
    < /code>
    < /li>
    < /ul>
    
     [b] наблюдения и вопросы < /strong> < /h3>  
       code 1 (инициализация на основе конструктора) значительно более медленнее (~ 2000 мс). < /strong> < /p>
    < /li >
       code 2 (статическая инициализация) ~ 66x быстрее (~ 30 мс).  < /strong> < /p>
    < /li>
    < /ul>
    Тем не менее,  на моей локальной машине (против компилятора), оба работают примерно через 30 секунд < /strong> с данными тестирования: < /p>
    vector nums(1e5, 1e9);
    int k = 70;
    
    Почему Leetcode показывает огромную разницу, но локально время выполнения схожи? H3>
    Я хотел бы понять, почему такое радикальная разница [/b] происходит между leetcode против моей локальной машины :

    создает ли LeetCode несколько экземпляров < /code> на тестовый пример? < /strong> < /p>


    < li> Если это так, это объяснило бы, почему инициализация на основе конструктора намного медленнее. < /li>
    < /ul>
    < /li>
    Есть ли какая -то модель оптимизации или выполнения компилятора, которая вызывает такое поведение? < /Strong> < /p>

    Понизирует ли компилятор LeetCode статическую инициализацию? < /Li>


может ли кеширование или повторное использование памяти повлиять на производительность на LeetCode?

< ul>
Статические переменные сохраняются по тестовым случаям. Может ли это повысить эффективность на LeetCode? < /Li>
< /ul>
< /li>
< /ol>
оценил бы любую информацию о Как различные модели выполнения Stravic Stime выполнения в C ++. 🚀

Подробнее здесь: https://stackoverflow.com/questions/793 ... -construct
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C++»