У меня есть большой (75000 x 5 x 6000) трехмерный массив, хранящийся в виде карты памяти NumPy. Если я просто перебираю первое измерение следующим образом:
import numpy as np
import time
a = np.memmap(r"S:\bin\Preprocessed\mtb.dat", dtype='float32', mode='r', shape=(75000, 5, 6000))
l = []
start = time.time()
index = np.arange(75000)
np.random.shuffle(index)
for i in np.array(index):
l.append(np.array(a[i]) * 0.7)
print(time.time() - start)
>>> 0.503
Итерация происходит очень быстро. Однако, когда я пытаюсь перебрать одну и ту же карту памяти в контексте более крупной программы, отдельные вызовы карты памяти будут занимать целых 0,1 секунды, а извлечение всех 75000 записей займет почти 10 минут.
Большая программа слишком длинная, чтобы воспроизводить ее здесь, поэтому мой вопрос: существуют ли какие-либо известные проблемы, которые могут привести к значительному замедлению доступа к memmap, возможно, если в памяти Python хранится значительный объем данных?
В более крупной программе использование выглядит так:
import time
array = np.memmap(self.path, dtype='float32', mode='r', shape=self.shape)
for i, (scenario_id, area) in enumerate(self.scenario_areas):
address = scenario_matrix.lookup.get(scenario_id)
if address:
scenario_output = array[address]
output_total = scenario_output * float(area)
cumulative += output_total # Add results to cumulative total
contributions[int(scenario_id.split("cdl")[1])] = output_total[:2].sum()
del array
Второй пример выполняется более 10 минут. Время строки scenario_output = array[address], которая просто извлекает запись из карты памяти, варьируется от 0,0 до 0,5 — полсекунды для извлечения одной записи.
r+
может вас тормозить.. - person Aaron   schedule 17.03.2017address
? Всегда ли это скаляр? - person user2357112 supports Monica   schedule 17.03.2017address
по порядку или разбросаны повсюду? время случайного поиска на диске может повредить скорости. - person hpaulj   schedule 17.03.2017line_profiler
иprofile
, чтобы узнать, где находятся узкие места, а затем попытаться их устранить. Повторяйте это, пока не будете удовлетворены. - person MSeifert   schedule 20.03.2017EmptyStandbyList.exe standbylist
и затем измерить время, скажем, для вашего простого скрипта. В этом случае не должно быть 0,5 секунды. - person pvg   schedule 20.03.2017