Есть таблица в текстовом файле, отформатированная пробелами. (~1000 строк и ~1000 столбцов.) Нужно превратить её в 2-мерный список. Сделал при помощи split() и splitlines(). Возник вопрос: как быстрее применить split() к результату splitlines()?
Можно заменять каждую строку на получаемый из неё список.
Можно создать пустой список и добавлять новые строки в него методом append().
Можно создать новый список через списковое включение (или как правильно называть list comprehension).
Ниже подсказали 4-й способ через map и lambda.
Решил померить:
#!/usr/bin/python3
from sys import argv
import time
replace, append, combine = 0.0, 0.0, 0.0
cycles = 20
for fil in argv[1:]:
ar = open( fil, 'rt' ).read()
for lcv in range(cycles):
lines = ar.splitlines()
t0 = time.perf_counter()
for line in range(len(lines)):
lines[line] = lines[line].split();
t1 = time.perf_counter()
replace += t1-t0
lines = ar.splitlines()
t0 = time.perf_counter()
lines2 = []
for line in range(len(lines)):
lines2.append( lines[line].split() );
t1 = time.perf_counter()
append += t1-t0
#lines = ar.splitlines()
t0 = time.perf_counter()
lines2 = [ l.split() for l in lines ]
t1 = time.perf_counter()
combine += t1-t0
#lines = ar.splitlines()
t0 = time.perf_counter()
lines2 = [*map(lambda x: x.split(), lines), ]
t1 = time.perf_counter()
lamb += t1-t0
print( 'replace, append, combine, lambda :',
replace/cycles, append/cycles, combine/cycles, lamb/cycles,
'100', append/replace*100, combine/replace*100, lamb/cycles*100 )
Результат неожиданный. При малом числе циклов 1-й способ на 5% медленнее 2-го и на 20% быстрее 3-го. При большом — 1-й на 10-15% быстрее и 2-го и 3-го. (4-й способ — между 1-м и 3-м, +10% на 1 цикле, +5% на 100.) Почему так происходит?
P.S. Вопрос не как радикально ускорить, а почему они так различаются и почему многократное повторение так меняет результат.