Lua: Как эффективно умножить все элементы в одномерной таблице, состоящей из чисел

Предположим, у нас есть таблица Lua с именем t, определенная следующим образом:

t = {4, 5, 6, 7}

Предположим, мы хотим узнать, каково произведение чисел в t. (В сторону: ответ 840.) Я могу придумать два метода.

Сначала базовый цикл for:

answer = 1
for i = 1, #t do
   answer = answer * t[i]
end
print ( answer )

Во-вторых, итератор ipairs:

answer = 1 
for i, j in ipairs ( t ) do
   answer = answer * j
end
print ( answer )

(Я полагаю, можно было бы также использовать итератор pairs.)

Мои вопросы:

  • Имеет ли какой-либо из двух показанных выше методов какие-либо реальные недостатки?
  • Существуют ли методы для получения желаемого значения answer, которые более эффективны и / или надежны, чем методы, показанные выше?

person Mico    schedule 30.05.2018    source источник
comment
print (840) - самый эффективный способ   -  person Jason Goemaat    schedule 31.05.2018
comment
@JasonGoemaat - Спасибо. Мой вопрос не о том, как распечатать известное число. Речь шла о том, как выполнить умножение всех элементов в таблице Lua, которая, как известно, состоит из чисел, предпочтительно эффективным способом. :-)   -  person Mico    schedule 31.05.2018


Ответы (1)


ipairs включает вызов функции. Это делает общий цикл for более медленным крошечным битом. Если внутренняя задача является чем-то сложным, накладные расходы на вызов функции будут незначительными, по сравнению с несколькими арифметическими операциями, в некоторых крайних случаях они могут быть заметными. Попытайся:

a={} 
for i=1,2e8 do a[i]=math.random() end
t=os.time()
q=1
for i=1,#a do q=q*a[i] end 
print(os.time()-t)
w=1
t=os.time()
for i,v in ipairs(a) do w=w*v end
print(os.time()-t)

Для меня результаты были 15 и 18. Это более эффективно, когда вычисление повторяется несколько раз (вложенные циклы):

a={} for i=1,1e4 do a[i]=math.random() end
t=os.time() q=1; for i=1,1e5 do for j=1,1e4 do q=q*a[j] end end print(os.time()-t)
t=os.time() q=1; for i=1,1e5 do for _,v in ipairs(a) do q=q*v end end print(os.time()-t)

Но все равно не много.

Если вам действительно нужно выжать даже этот бит производительности, вам, вероятно, следует взглянуть на luajit и различные числовые фреймворки. на его основе: 1, 2, 3. Кроме того, есть статья автора языка по оптимизации.

person Dimitry    schedule 30.05.2018