#java #performance #optimization #runtime
#java #Производительность #оптимизация #время выполнения
Вопрос:
for (int i = 0,len=size-2; i < len; i ) {
for (int j = 1,leng = size-1; j < leng; j ) {
for (int k = 2; k < size; k ) {
if (i < j amp;amp; j < k) {
sum = sum Math.floor((a[i] a[j] a[k]) / (a[i] * a[j] * a[k]));
}
}
}
}
Мне нужно, чтобы этот фрагмент кода выполнялся как минимум за половину текущего времени выполнения.Здесь массив ‘a’ имеет тип double . Я принимаю входные данные через класс reader. Как добиться более быстрого времени выполнения?
Комментарии:
1. Чего вы пытаетесь достичь с помощью этого кода?
2. @MichaelPickett Я должен выполнить суммирование для триплета массива. Код выполняет свою работу. Мне просто нужно, по крайней мере, половину времени выполнения.
3. Мне кажется, что этот код выполняет одно и то же несколько раз. Наиболее примечательно, что каждый
i
циклj
суммирует иk
минус 1 местоположение.4. @MichaelPickett Я этого не понял. Не могли бы вы уточнить?
5. @Treycos В массиве N элементов. Я должен суммировать триплеты x, y, z так, чтобы 0 <=x<y<z<=N-1.
Ответ №1:
Ваши вложенные циклы ничего не делают, кроме повторения, если условие i < j amp;amp; j < k
не выполнено. Но средний и внутренний циклы начинают свои итерации с одного и того же начального значения каждый раз, независимо от значений индексов внешнего цикла. Например, когда i
is 5
, средний цикл все еще начинается с 1
, а внутренний цикл все еще начинается с 2
, даже если они могут знать, что они не будут выполнять никакой полезной работы для этих значений.
Начинайте каждый цикл с более полезной точки. Вы сэкономите много бесполезной индексной арифметики и много тщетных сравнений индексов. На самом деле, если вы делаете это правильно, вам вообще не нужно выполнять какие-либо сравнения индексов.
Детали, такие, какие они есть, оставлены в качестве упражнения. Я, вероятно, уже предложил слишком много помощи.
Комментарии:
1. Да, у вас есть. Большое вам спасибо. 🙂
Ответ №2:
Вы можете переписать 1/(x*y*z)
как 1*(1/x)*(1/y)*(1/z)
. Умножение происходит быстрее, чем деление. Вы можете предварительно вычислить массив обратных значений как ra[i] = 1/a[i]
. Могут быть дальнейшие оптимизации, но это зависит от того, какие значения могут быть, вы не ответили на этот вопрос.
Ответ №3:
С этим кодом не будет необходимости в операторе if: x
всегда уступает y
, который всегда уступает z
for (int x = 0; x < size - 2; x )
for(int y = x 1; y < size - 1; y )
for(int z = y 1; z < size; z )
sum = Math.floor((a[x] a[y] a[z]) / (a[x] * a[y] * a[z]));
Комментарии:
1. Спасибо. Но, к сожалению, это не повлияло на время выполнения.
2. Операция в Math.floor() может занимать около 99% времени выполнения, это единственное, что вы можете улучшить
3. Я не вижу другого пути: (
4. Ммм… зачем вам Math.floor()?, Попробуйте без него и проверьте время выполнения, чтобы увидеть, соответствует ли это pb
5. проблема в том, что оператор floor является частью функции суммирования.