Оптимизация программ на Python
Как ускорить программу на Python (pdf)
Бенчмарки
Ниже собраны программы, измеряющие время работы разных вариантов кода на Python. В начале каждой программы приведён пример вывода. Запустите их у себя, чтобы получить время работы на своём компьютере.
print(..., file=f) vs. f.write(...)
# Example output:
# Read 1000000 numbers using "int(input())" in 1.8937892050016671 seconds
# Read 1000000 numbers using "int(sys.stdin.readline())" in 0.6622662610025145 seconds
import os
import random
import sys
import time
DATA_SIZE = 10 ** 6
FILE_NAME = 'tmp_feocuysg.txt'
DATA = list(range(DATA_SIZE))
original_stdin = None
def prepare_file():
global original_stdin
random.shuffle(DATA)
with open(FILE_NAME, 'w') as f:
for x in DATA:
f.write(str(x) + '\n')
original_stdin, sys.stdin = sys.stdin, open(FILE_NAME)
def cleanup_file():
global original_stdin
sys.stdin.close()
original_stdin, sys.stdin = None, original_stdin
os.remove(FILE_NAME)
def test_input():
prepare_file()
start = time.perf_counter()
x = 0
for i in range(DATA_SIZE):
x += int(input())
elapsed = time.perf_counter() - start
cleanup_file()
return elapsed
def test_readline():
prepare_file()
start = time.perf_counter()
x = 0
for i in range(DATA_SIZE):
x += int(sys.stdin.readline())
elapsed = time.perf_counter() - start
cleanup_file()
return elapsed
elapsed = test_input()
print('Read {} numbers using "int(input())" in {} seconds'
.format(DATA_SIZE, elapsed))
elapsed = test_readline()
print('Read {} numbers using "int(sys.stdin.readline())" in {} seconds'
.format(DATA_SIZE, elapsed))
input() vs. stdin.readline()
# Example output
# Wrote 1000000 numbers using "print(x, file=f)" in 1.6223861339967698 seconds
# Wrote 1000000 numbers using "f.write(str(x) + '\n')" in 0.7785177710029529 seconds
import os
import random
import time
DATA_SIZE = 10 ** 6
FILE_NAME = 'tmp_caiorsg.txt'
DATA = list(range(DATA_SIZE))
def prepare_data():
random.shuffle(DATA)
return DATA
def test_print():
data = prepare_data()
with open(FILE_NAME, 'w') as f:
start = time.perf_counter()
for x in data:
print(x, file=f)
elapsed = time.perf_counter() - start
os.remove(FILE_NAME)
return elapsed
def test_write():
data = prepare_data()
with open(FILE_NAME, 'w') as f:
start = time.perf_counter()
for x in data:
f.write(str(x) + '\n')
elapsed = time.perf_counter() - start
os.remove(FILE_NAME)
return elapsed
elapsed = test_print()
print('Wrote {} numbers using "print(x, file=f)" in {} seconds'
.format(DATA_SIZE, elapsed))
elapsed = test_write()
print('Wrote {} numbers using "f.write(str(x) + \'\\n\')" in {} seconds'
.format(DATA_SIZE, elapsed))
Код на верхнем уровне vs. Код в функции
# Example output:
# Sum of 10000000 numbers on module level in 5.0005733920042985 seconds
# Sum of 10000000 numbers on function level in 3.303951841997332 seconds
import os
import random
import time
DATA_SIZE = 10 ** 7
DATA = list(range(DATA_SIZE))
def prepare_data():
random.shuffle(DATA)
return DATA
def main():
data = prepare_data()
start = time.perf_counter()
a = 0
for i in range(DATA_SIZE):
a += data[i] if i&1 else -data[i]
return time.perf_counter() - start
# Top-level
data = prepare_data()
start = time.perf_counter()
a = 0
for i in range(DATA_SIZE):
a += data[i] if i&1 else -data[i]
elapsed = time.perf_counter() - start
print('Sum of {} numbers on module level in {} seconds'
.format(DATA_SIZE, elapsed))
# Function
elapsed = main()
print('Sum of {} numbers on function level in {} seconds'
.format(DATA_SIZE, elapsed))
a.append(...) vs. a[i] = ... vs. a = [... for i in range(...)]
# Example output:
# Read 1000000 numbers into array using "a.append(int(f.readline()))" in 0.5692962329994771 seconds
# Read 1000000 numbers into array using "a[i] = int(f.readline())" in 0.5054713299978175 seconds
# Read 1000000 numbers into array using "a = [int(f.readline()) for i in range(n)]" in 0.5023784420045558 seconds
import os
import random
import time
DATA_SIZE = 10 ** 6
FILE_NAME = 'tmp_fovbeas.txt'
DATA = list(range(DATA_SIZE))
def prepare_file():
random.shuffle(DATA)
with open(FILE_NAME, 'w') as f:
for x in DATA:
f.write(str(x) + '\n')
return open(FILE_NAME)
def cleanup_file():
os.remove(FILE_NAME)
def test_append():
with prepare_file() as f:
start = time.perf_counter()
a = []
for i in range(DATA_SIZE):
a.append(int(f.readline()))
elapsed = time.perf_counter() - start
cleanup_file()
return elapsed
def test_assign():
with prepare_file() as f:
start = time.perf_counter()
a = [0] * DATA_SIZE
for i in range(DATA_SIZE):
a[i] = int(f.readline())
elapsed = time.perf_counter() - start
cleanup_file()
return elapsed
def test_generator():
with prepare_file() as f:
start = time.perf_counter()
a = [int(f.readline()) for i in range(DATA_SIZE)]
elapsed = time.perf_counter() - start
cleanup_file()
return elapsed
elapsed = test_append()
print('Read {} numbers into array using "a.append(int(f.readline()))" in {} seconds'
.format(DATA_SIZE, elapsed))
elapsed = test_assign()
print('Read {} numbers into array using "a[i] = int(f.readline())" in {} seconds'
.format(DATA_SIZE, elapsed))
elapsed = test_generator()
print('Read {} numbers into array using "a = [int(f.readline()) for i in range(n)]" in {} seconds'
.format(DATA_SIZE, elapsed))