2015-01-04 10 views
0

Я пробовал эту проблему при вызове leetcode Plus One.Почему разница во времени?

Учитывая неотрицательное число, представленное в виде массива цифр, плюс один к числу. Цифры хранятся так, что самая значимая цифра находится во главе списка.

У одного из моих решений было время работы 380 мс. Я жестко закодировал некоторые значения, а время работы увеличилось до 412 мс. Может ли кто-нибудь объяснить, что вызывает это изменение? Я думал, что время выполнения уменьшится, так как значения не будут вычислены.

Вот код с запуском время 380ms:

public int[] plusOne(int[] digits) { 
    int len = digits.length; 

    digits[len - 1] += 1; 


    if(digits[len - 1] < 10) { 
     return digits; 
    } 
    else { 
     //for(int i = len - 1; i >= 0; i--) 
     int i = len - 1; 
     while(digits[i] > 9) { 

      if(i == 0) { 
       int[] ans = new int[digits.length + 1]; 
       ans[0] = digits[0]/10; 
       ans[1] = digits[0] % 10; 
       for(int n = 1; n < len; n++) { 
        ans[n + 1] = digits[n]; 
       } 
       return ans; 
      } 
      else { 
       int last = digits[i]; 
       digits[i] = last % 10; 
       digits[i - 1] += last/10; 
       i--; 

      } 

     } 
     return digits; 
    } 
} 

Это один взял 412ms:

public int[] plusOne(int[] digits) { 
    int len = digits.length; 

    digits[len - 1] += 1; 


    if(digits[len - 1] < 10) { 
     return digits; 
    } 
    else { 
     //for(int i = len - 1; i >= 0; i--) 
     int i = len - 1; 
     while(digits[i] > 9) { 

      if(i == 0) { 
       int[] ans = new int[digits.length + 1]; 
       ans[0] = 1; 
       ans[1] = 0; 
       for(int n = 1; n < len; n++) { 
        ans[n + 1] = digits[n]; 
       } 
       return ans; 
      } 
      else { 
       int last = digits[i]; 
       digits[i] = 0; 
       digits[i - 1] += 1; 
       i--; 

      } 

     } 
     return digits; 
    } 
} 
+1

ли это средний результат, или запустить его только один раз? Поскольку удержание времени только на один прогон, это не так эффективно, потому что многие факторы могут внести свой вклад в долгосрочной перспективе. –

+0

Выполняете ли вы это на специализированной машине с повторяемыми результатами или нагрузка на машины и, следовательно, время проведения теста несколько случайное? –

+0

Я не запускал это на своей машине. Я отправил код в LeetCode OJ, и именно там я увидел разницу во времени выполнения. Спасибо всем за ответы! :) Есть много, чтобы учиться, и вы все наверняка добавили мне свои знания. – strider14

ответ

0

Некоторые из основных факторов, которые могут повлиять на результаты синхронизации являются:

  • JVM разогреть
  • сборщик мусора
  • оптимизацию компилятора вы не видите (изменение порядка и так далее) - для Вашего случай ans[0] = digits[0]/10;ans[1] = digits[0] % 10; и т. д. могут быть оптимизированы уже до фиксированного значения, так как эти значения никогда не меняются.
  • другие запущенные процессы в вашей OS/машины, которые потребляют ресурсы

Вы должны разогреть JVM, прежде чем принимать реальные расчеты, как сделать это? сделайте некоторые тестовые измерения перед фактическим измерением (убедитесь, что для прогрева требуется несколько секунд). Я лично никогда не решаю, когда контрольные тайминги составляют менее 1 секунды, и я пытаюсь создать большую проблему, чтобы увидеть фактические результаты.

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

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

//after the warm up try the following 
int repetitions = 1000; 
start = System.nanoTime(); 
for (int i=0; i<repetitions; i++) { 
    //your calculations 
} 
end = System.nanoTime(); 
System.out.println("Cost per repetition: " + (end - start)/repetitions); 

Есть некоторые инструменты, а также, см Caliper проект

0

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

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

0

Программа с 380 мс:

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

, такие как:

digits[i] = 0; 
ans[0] = 1; 
ans[1] = 0; 

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

такой как:

digits[i] = last % 10; 
ans[0] = digits[0]/10; 
ans[1] = digits[0] % 10; 

Разница во времени возникает из-за этого.

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

0

Это действительно зависит от состояния вашего компьютера. Процесс будет работать быстрее иногда. Вам нужно тестировать программу много раз. Кроме того, он вычисляется в мс, миллисекундах. A ms - 1/1000 секунды. На самом деле не имеет значения, есть ли у несколько разностей мс. Разделить - очень простой расчет (для компьютеров). Современные процессоры могут завершить его очень очень короткое время. Вы не используете процессоры с 1900-х годов.

Как вывод, вы просто удаляли некоторые подразделения, что означает, что вы не получите большой задержки. Не обращайте внимания на крошечную задержку;) Ваша IDE может компилировать другие проекты, когда вы запускали второй код.

Смежные вопросы