TL; DR Вопрос
Относительно numpy массивов, которые являются соседними C или F смежными (флаги c_contiguous и f_contiguous в массиве ложны):
- Может ли массив действительно быть ни C, ни F смежными? Или ложные флаги просто означают, что numpy не может определить правильный тип contigious?
- Каковы последствия для производительности таких массивов? Есть ли какие-то оптимизации, которые мы упускаем, оставаясь в этом состоянии?
Массив, например:
import numpy as np
arr = np.random.randint(0, 255, (1000, 1000, 3), dtype='uint8')
arr = arr[:, :, ::-1]
assert arr.flags.c_contiguous is False
assert arr.flags.f_contiguous is False
Фон
Я пытаюсь оптимизировать простой код блок, который вызывается много раз в течение программы.
Этот блок кода отвечает за загрузку изображения PIL, преобразование его в массив numpy, инвертирование его каналов и возврат.
Примерно так:
import numpy as np
from PIL import Image
def load_image(path):
arr = np.asarray(Image.open(path).convert('RGB'))
return arr[:, :, ::-1].copy()
Исходный вызов copy()
был нужен для того, чтобы вернуть возвращаемое значение в виде массива C -order, однако мне было интересно, есть ли способ достичь того же эффекта, не копируя массив каждый раз, поскольку это звучит очень дорого.
Я попытался заменить вызов copy()
на np.ascontiguousarray()
, но тесты показали, что они такие же, поэтому я предполагаю, что он также выполняет копирование за кулисами.
Я решил применить это решение в конце:
import numpy as np
from PIL import Image
def load_image(path):
arr = np.ascontiguousarray(Image.open(path).convert('RGB'))
return arr[:, :, ::-1]
Здесь я конвертирую изображение в массив, упорядоченный по C, который может копировать за кулисами, но на самом деле это не так, потому что в тестах эта функция на X3-X4 быстрее, чем предыдущая.
Однако я хочу быть уверенным, что не отменю никаких будущих оптимизаций, вернув массив, который не является ни C, ни Заказано F.