Оптимизация производительности алгоритма подсчета в Pypy vs Python (Numpy vs List)

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

У меня есть два вопроса:

  1. Почему pypy значительно медленнее с numpy?
  2. Есть ли что-нибудь, что я могу сделать, чтобы оптимизировать мой алгоритм, чтобы сделать pypy (или python) быстрее?

Результирующие тайминги:

Python 2.7.5

  • # очков: 16 777 216 (8 ** 3 * 32 ** 3)
  • Время перерыва: 1487.15 мс
  • Xrange Numpy время: 2553.98 мс
  • Point Gen Время: 6162,23 мс
  • Время генерации музыки: 13894.73 мс

Pypy 2.2.1

  • # очков: 16 777 216 (8 ** 3 * 32 ** 3)
  • Время переключения: 129,48 мс
  • Время перезарядки: 4644.12 мс
  • Point Gen Время: 4643,82 мс
  • Время генерации музыки: 44168.98 мс

Алгоритм :

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

def generate(size=32, point=(0, 0, 0), width=32): """ generate points in space around a center point with a specific width and number of divisions (size) """ X, Y, Z = point half = width * 0.5 delta = width scale = width / size offset = scale * 0.5 X = X + offset - half Y = Y + offset - half Z = Z + offset - half for x in xrange(size): x = (x * scale) + X for y in xrange(size): y = (y * scale) + Y for z in xrange(size): z = (z * scale) + Z yield (x, y, z) 

При оптимизации я начал изучать использование pypy, а не python. И, сравнивая эти два, я придумал несколько разных сценариев:

  • подсчет с использованием xrange

     rsize = 8 # size of region csize = 32 # size of chunk number_of_points = rsize ** 3 * csize ** 3 [x for x in xrange(number_of_points)] 
  • подсчет с использованием xrange с numpy

     rsize = 8 # size of region csize = 32 # size of chunk number_of_points = rsize ** 3 * csize ** 3 np.array([x for x in xrange(number_of_points)]) 
  • работа с алгоритмом выше

     rsize = 8 # size of region csize = 32 # size of chunk [p for rp in generate(size=rsize, width=rsize*csize) for p in generate(size=csize, width=csize, point=rp)] 
  • выполнение алгоритма выше с помощью numpy

     rsize = 8 # size of region csize = 32 # size of chunk np.array([p for rp in generate(size=rsize, width=rsize*csize) for p in generate(size=csize, width=csize, point=rp)]) 

Задний план:

Я пытаюсь создать движок voxel, и я хочу оптимизировать свой алгоритм, чтобы сократить время генерации до уровня, который можно контролировать. Хотя я, очевидно, не добьюсь чего-то близкого к Java / C ++, я бы хотел как можно больше нажать python (или pypy).

Я заметил, что просмотры списков значительно быстрее, чем словари из более ранних таймингов. И списки также быстрее, чем кортежи (неожиданные), хотя кортежи генерируются быстрее. У Numpy есть еще более быстрое время чтения, чем не-numpy. Однако время создания numpy может на несколько порядков меньше.

Поэтому, если чтение является самым важным, есть явное преимущество для использования numpy. Однако, если чтение и создание имеют одинаковую важность, то прямой список, вероятно, лучше всего. Тем не менее, у меня нет чистого способа взглянуть на использование памяти, но я подозреваю, что списки намного менее эффективны в памяти, чем кортежи или numpy. Кроме того, хотя это небольшая разница, я нашел .get в словаре немного быстрее, чем использование вызова __ getitem __ (т.е. словарь [lookup] vs. dicitonary.get (lookup))

тайминги …

Python 2.7.5

чтение

  - Option 1: tuple access... 2045.51 ms - Option 2: tuple access (again)... 2081.97 ms # sampling effect of cache - Option 3: list access... 2072.09 ms - Option 4: dict access... 3436.53 ms - Option 5: iterable creation... N/A - Option 6: numpy array... 1752.44 ms 

Создание

  - Option 1: tuple creation... 690.36 ms - Option 2: tuple creation (again)... 716.49 ms # sampling effect of cache - Option 3: list creation... 684.28 ms - Option 4: dict creation... 1498.94 ms - Option 5: iterable creation... 0.01 ms - Option 6: numpy creation... 3514.25 ms 

Pypy 2.2.1

чтение

  - Option 1: tuple access... 243.34 ms - Option 2: tuple access (again)... 246.51 ms # sampling effect of cache - Option 3: list access... 139.65 ms - Option 4: dict access... 454.65 ms - Option 5: iterable creation... N/A - Option 6: numpy array... 21.60 ms 

Создание

  - Option 1: tuple creation... 1016.27 ms - Option 2: tuple creation (again)... 1063.50 ms # sampling effect of cache - Option 3: list creation... 365.98 ms - Option 4: dict creation... 2258.44 ms - Option 5: iterable creation... 0.00 ms - Option 6: numpy creation... 12514.20 ms 

Во всех примерах случайный поиск был создан для случайных данных.

 dsize = 10 ** 7 # or 10 million data points data = [(i, random.random()*dsize) for i in range(dsize)] lookup = tuple(int(random.random()*dsize) for i in range(dsize)) 

Петли были очень просты:

 for x in lookup: data_of_specific_type[x] 

И data_of_specific_type – это преобразование данных в этот тип (например, кортеж (данные), список (данные) и т. Д.)

One Solution collect form web for “Оптимизация производительности алгоритма подсчета в Pypy vs Python (Numpy vs List)”

Часть вопроса такова:

 np.array([p for rp in generate(size=rsize, width=rsize*csize) for p in generate(size=csize, width=csize, point=rp)]) 

np.array работа по созданию list и преобразованию его в np.array .

Более быстрый способ сделать это:

 arr = np.empty(size) i = 0 for rp in generate(size=rsize, width=rsize*csize): for p in generate(size=csize, width=csize, point=rp): arr[i] = p i += 1 
  • Где я могу узнать больше о функции перевода PyPy?
  • Как запустить пип-код другой версии python с помощью команды python?
  • как отключить утверждение pypy assert?
  • Есть ли какой-нибудь инструмент для преобразования базы данных cython обратно в чистый python?
  • PyPy - Как он может победить CPython?
  • Без стеков в PyPy и PyPy + greenlet - отличия
  • Работает ли PyPy с asyncio?
  • Python: JIT для известных узких мест
  • Python - лучший язык программирования в мире.