#performance #cython
#Производительность #cython
Вопрос:
Я пытаюсь прочитать файл ascii (текстовый) определенного формата. Я выполнил некоторое профилирование строк, и запись времени используется в цикле. Я пытаюсь, можно ли улучшить производительность кода внутри цикла.
Что я пробовал
-
Более быстрая индексация массива numpy путем инициализации массива numpy с интерфейсом буфера, как в официальных документах, что, как я ожидал, значительно ускорит процесс, но едва ли что-то изменило.
-
Пользовательская функция преобразования типов (без взаимодействия с python) для замены int (строка [0: 5]), но это оказалось довольно дорогостоящим
Пользовательская функция для преобразования типов
cdef int fast_atoi(str buf):
cdef int i=0 ,c = 0, x = 0
for i in range(5):
c = buf[i]
if c > 47 and c < 58:
x = x * 10 c - 48
return x
Основной блок кода, который я хочу оптимизировать
def func(filename):
cdef np.ndarray[np.int32_t] a1
cdef np.ndarray[object] a2
cdef np.ndarray[object] a3
cdef np.ndarray[np.int32_t] a4
cdef int count = 0
cdef int n_lines
cdef str line
with open(filename) as inf:
next(inf)
n_lines = int(next(inf))
a1 = np.zeros(n_atoms, dtype=np.int32)
a2 = np.zeros(n_atoms, dtype=object)
a3 = np.zeros(n_atoms, dtype = object)
a4 = np.zeros(n_atoms, dtype=np.int32)
for i,line in enumerate(inf):
if i == n_lines:
break
try:
a1[i] = int(line[0:5]) #custom function fast_atoi(line[0:5])
a2[i] = line[5:10].strip()
a3[i] = line[10:15].strip()
a4[i] = int(line[15:20])
except (ValueError, TypeError) as e:
break
У меня есть файл размером 4,3 МБ
Author
n_lines
1xyz A 1 5.202 4.356 3.155
1mno A1 2 5.119 4.411 3.172
1mno A2 3 5.155 4.283 3.104
1nnn B3 4 5.247 4.318 3.237
1xax KA 5 5.306 4.421 3.075
1ooo MA 6 5.383 4.347 3.054
1cbd NB 7 5.257 4.474 2.941
1orc OB1 8 5.189 4.404 2.893
Текущая реализация занимает в среднем 76 мс на моем компьютере, добавление упомянутой пользовательской функции ухудшает ситуацию.
Я был бы очень признателен, если бы можно было предложить некоторые улучшения. Я новичок в cython.
Комментарии:
1. Вы пробовали
pandas
программу чтения CSV?2. Да, просто дороже. Поскольку при чтении файла выполняется обработка строк, считывается файл, который не является таким прямым при чтении pandas.
3. Вероятно, вы хотите отключить проверку границ для своей функции. Также может потребоваться преобразовать ваш str в массив символов, я не знаю, если cython автоматически оптимизирует доступ к строке python. Вы можете получить аннотированный отчет от компилятора cython с помощью
cython -a
, любые строки, выделенные желтым в отчете, имеют некоторые накладные расходы python, от которых вы захотите избавиться.4. Спасибо за предложения @ngoldbaum.