У меня есть вектор v
, который имеет много нулей и только пару ненулевых элементов (в основном 1 с). У меня есть матрица m
, которая является квадратной, симметричной и имеет целочисленные значения.
Тестовый скрипт
Следующий скрипт генерирует аналогичные данные и время интересующей меня части:
#!/usr/bin/env python
import time
import numpy as np
np.random.seed(0)
n = 20000
m = 20
assert n >= m
# Create the vector
v = [1] * m + [0] * (n - m)
np.random.shuffle(v)
v = np.array(v, np.int8)
# Create the matrix
m = np.random.randint(0, 256, size=(n, n), dtype=np.uint8)
m = (m + m.T) / 2
m = m.astype(np.uint8)
# Multiplication
t0 = time.time()
result = np.dot(v, m)
t1 = time.time()
# Check the results
print("result shape: {}".format(result.shape))
print("result[0]: {}".format(result[0])) # should be 1757
print('Time: {:0.2f}s'.format(t1 - t0))
Результаты испытаний
Я проверил пару вариантов вышеописанного скрипта:
| Variation | Time |
| ------------------------------------------------- | ------ |
| Original | 21.65s |
| (1) m = m.astype(np.float32) | 0.09s |
| (2) v = v.astype(np.uint8) | 4.87s |
| (3) v = v.astype(np.int16);m = m.astype(np.int16) | 5.77s |
| (4) = (3) + matmul instead of dot | 6.91s |
| (5) = (1) + matmul instead of dot | 0.09s |
Вопрос
Глядя на результаты моего теста, у меня есть два вопроса:
- Почему такая огромная разница? Это проверка типа / границы?
- Есть ли другой способ ускорить его; например разреженные матрицы? (Я пытался использовать
v = scipy.sparse.csr_matrix(v)
, но я не получаю тот же результат)