Самый быстрый способ добавить / умножить два скалярных числа с плавающей запятой в Python - PullRequest
0 голосов
/ 18 сентября 2018

Я использую python, и, очевидно, самая медленная часть моей программы - простые добавления к переменным с плавающей точкой.

Для выполнения 400 000 000 сложений / умножений требуется около 35 секунд.

Я пытаюсь выяснить, какой самый быстрый способ я могу сделать эту математику.

Вот так выглядит структура моего кода. Пример (фиктивный) код:

def func(x, y, z):
    loop_count = 30
    a = [0,1,2,3,4,5,6,7,8,9,10,11,12,...35 elements]
    b = [0,11,22,33,44,55,66,77,88,99,1010,1111,1212,...35 elements]
    p = [0,0,0,0,0,0,0,0,0,0,0,0,0,...35 elements]
    for i in range(loop_count - 1):
        c = p[i-1]
        d = a[i] + c * a[i+1]
        e = min(2, a[i]) + c * b[i]
        f = e * x
        g = y + d * c
        .... and so on
        p[i] = d + e + f + s + g5 + f4 + h7 * t5 + y8
    return sum(p)

func() вызывается около 200к раз. loop_count составляет около 30. И у меня ~ 20 умножений и ~ 45 сложений и ~ 10 использований min / max

Мне было интересно, есть ли метод для меня, чтобы объявить все это как ctypes.c_float и сделать добавление в C, используя stdlib или что-то подобное?

Обратите внимание , что p[i], вычисленный в конце цикла, используется как c в следующей итерации цикла. Для итерации 0 он просто использует p [-1], который в данном случае равен 0.

Мои ограничения:

  • Мне нужно использовать Python. Хотя я понимаю, что простая математика будет быстрее в C / Java / и т.д. Я не могу использовать его из-за множества других вещей, которые я делаю в Python, что нельзя сделать в C в этой же программе.
  • Я пытался написать это с помощью Cython, но это вызвало кучу проблем со средой, в которой мне нужно было выполнить это. Итак, опять же - не вариант.

1 Ответ

0 голосов
/ 19 сентября 2018

Я думаю, вам стоит подумать об использовании numpy. Вы не упомянули никаких ограничений.

Пример случая простой точечной операции (x.y)

import datetime
import numpy as np

x = range(0,10000000,1)
y = range(0,20000000,2)
for i in range(0, len(x)):
    x[i] = x[i] * 0.00001
    y[i] = y[i] * 0.00001

now =  datetime.datetime.now()
z = 0
for i in range(0, len(x)):
    z = z+x[i]*y[i]
print "handmade dot=", datetime.datetime.now()-now
print z

x = np.arange(0.0, 10000000.0*0.00001, 0.00001)
y = np.arange(0.0, 10000000.0*0.00002, 0.00002)

now =  datetime.datetime.now()
z = np.dot(x,y)
print 'numpy dot =',datetime.datetime.now()-now
print z

выходы

handmade dot= 0:00:02.559000
66666656666.7
numpy dot = 0:00:00.019000
66666656666.7

numpy более чем в 100 раз быстрее.

Причина в том, что numpy инкапсулирует библиотеку C, которая выполняет операцию с точкой со скомпилированным кодом. В полном Python у вас есть список потенциально общих объектов, приведение, ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...