Кто-нибудь может предложить более быстрый способ создания этого массива? - PullRequest
0 голосов
/ 02 марта 2020

Я создаю этот массив для генерации индексов для моего шейдера. Этот метод oop медленный. Кто-нибудь может предложить более быстрый метод для вычисления этого массива?

elems = []
ring_c = 24
slice_c = 235030
for si in range(slice_c - 1):
    elems += [si * ring_c, si * ring_c]
    for ri in range(ring_c + 1):
        ie = ri % ring_c
        elems += [ie + si * ring_c, ie + (si + 1) * ring_c]
elems = np.array(elems, dtype=np.int32)

1 Ответ

1 голос
/ 02 марта 2020

Используйте NumPy возможности векторизации и вещания для ускорения расчетов. Это был бы подход с моей стороны, включая некоторые моменты времени (если честно, читаемость кода значительно снижается по сравнению с исходным подходом l oop, но если скорость важнее всего ...):

import numpy as np
import time

ring_c = 24
slice_c = 235030

tic = time.perf_counter()

# Original solution
elems = []
for si in range(slice_c - 1):
    elems += [si * ring_c, si * ring_c]
    for ri in range(ring_c + 1):
        ie = ri % ring_c
        elems += [ie + si * ring_c, ie + (si + 1) * ring_c]

toc = time.perf_counter()

print('Time original solution [s]:', toc - tic)


tic = time.perf_counter()

# Vectorized approach
my_si = np.arange(slice_c - 1)
my_elems = np.repeat(ring_c * my_si, 2)
temp = np.empty(2 * my_si.size, my_si.dtype)
temp[0::2] = my_si
temp[1::2] = my_si + 1
my_ri = np.arange(ring_c + 1)
my_ie = np.expand_dims(my_ri % ring_c, axis=1)
my_si = temp * ring_c + my_ie
my_elems = np.vstack((my_elems, my_si))
N = my_elems.shape[1] // (slice_c - 1)
my_elems = list(my_elems.reshape((my_elems.shape[0], -1, N)).swapaxes(0, 1).reshape((np.prod(my_elems.shape), -1)).squeeze())

toc = time.perf_counter()

print('Time vectorized approach [s]: ', toc - tic)

print('Number of different elements: ', np.sum(np.abs(np.array(elems) - np.array(my_elems))))

Вывод:

Time original solution [s]: 4.765700837
Time vectorized approach [s]:  0.6265843100000001
Number of different elements:  0

Надеюсь, это поможет!

----------------------------------------
System information
----------------------------------------
Platform:    Windows-10-10.0.16299-SP0
Python:      3.8.1
NumPy:       1.18.1
----------------------------------------

РЕДАКТИРОВАТЬ: Для меньших массивов решение l oop быстрее, чем этот векторизованный подход!

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