Не так давно я натрапив на пост, де порівнювались різні методи коду для пошуку цифр у рядках у Python. Виникло бажання перевірити реальні швидкості цих методів, тому вирішив самостійно провести експеримент.
Я розглянув, як швидко кожен метод виконується при пошуку цифр коротких рядках, а також порівняємо їхню ефективність з погляду часу виконання.
Надалі, порівнявши кілька підходів, я поділюсь висновками щодо того, який з них є найкращим в умовах реального використання Python для цієї задачі.
![]() |
Шість версій для порвняння |
Ось результати порівняння середнього часу виконання 10 мільйонів спроб з використанням: MacOS, Python 3.13.0:
![]() |
Найкращий по швидкості варіант - Version_6 |
Але для мене було здивування, чому 5 версія повільніша за 4 ту, я гадав що REGEX = re.compile(r"\d+"), пришвидшує роботу.
Але після порівняння 5 версій, я додав шосту версію котра стала найкращою і довела що у випадку використання pre compiled Patterns в re не спрацьовує принцип відносності - літак летить на повітря чи повітря летить на літак 😁. І має велику різницю код:
re.findall(REGEX, text)
REGEX.findall(text)
Код метода порівняння:
import timeit | |
from matplotlib.colors import ListedColormap | |
import matplotlib.pyplot as plt | |
import re | |
def version_1(string: str) -> str: | |
digits = [] | |
for char in string: | |
if char.isdigit(): | |
digits.append(char) | |
return "".join(digits) | |
def version_2(string: str) -> str: | |
return "".join([char for char in string if char.isdigit()]) | |
def version_3(string: str) -> str: | |
return "".join(filter(str.isdigit, string)) | |
def version_4(string: str) -> str: | |
return "".join(re.findall(r"\d+", string)) | |
REGEX = re.compile(r"\d+") | |
def version_5(string: str) -> str: | |
return "".join(re.findall(REGEX, string)) | |
def version_6(string: str) -> str: | |
return "".join(REGEX.findall(string) | |
) | |
def plot_mesures_bar(plot_results: dict, output_file="performance_comparison.png"): | |
plt.figure(figsize=(12, 8)) | |
x = [i[0].title() for i in plot_results.items()] | |
y = [i[1][0] for i in plot_results.items()] | |
palette = ListedColormap(plt.get_cmap('Set1').colors) | |
num_colors = len(palette.colors) | |
colors = [palette(i % num_colors) for i in range(len(x))] | |
plt.bar(x, y, color=colors) | |
plt.title("Performance Comparison of Different Versions") | |
plt.xlabel("Version") | |
plt.ylabel("Average Time (seconds)") | |
plt.grid(True) | |
# plt.legend() | |
plt.tight_layout() | |
plt.savefig(output_file, dpi=300) # Save as PNG with high resolution | |
print(f"Saved results to: {output_file}") | |
functions_list = [ | |
(lambda: version_1(test_str), "version_1"), | |
(lambda: version_2(test_str), "version_2"), | |
(lambda: version_3(test_str), "version_3"), | |
(lambda: version_4(test_str), "version_4"), | |
(lambda: version_5(test_str), "version_5"), | |
(lambda: version_6(test_str), "version_6"), | |
] | |
categories = ["lexxai_2024"] | |
times = 10_000_000 | |
repeat = 8 | |
print(f"{times=}, {repeat=}") | |
results = {fun_name: [] for _, fun_name in functions_list} | |
test_str = categories[0] | |
for fun, fun_name in functions_list: | |
result_version = fun() | |
time_version = timeit.repeat(fun, number=times, repeat=repeat) | |
avg_time_version = sum(time_version) / len(time_version) | |
results[fun_name].append(avg_time_version) | |
print( | |
f" - {fun_name.title()}. Time: {[f'{t:.4f}' for t in time_version]} " | |
f"avg: {avg_time_version:.4f} seconds. Result: {result_version}" | |
) | |
plot_mesures_bar(results) | |
print("Press Enter to exit...") | |
input() | |
""" | |
Python 3.13.0 | |
times=10000000, repeat=8 | |
- Version_1. Time: ['9.6431', '9.3966', '9.4082', '9.4500', '9.3949', '9.3880', '9.4951', '9.4736'] avg: 9.4562 seconds. Result: 2024 | |
- Version_2. Time: ['8.8718', '9.0103', '9.2408', '8.7917', '8.8005', '9.0065', '8.7919', '8.8034'] avg: 8.9146 seconds. Result: 2024 | |
- Version_3. Time: ['8.4679', '8.0702', '8.2425', '7.7790', '12.5577', '10.3317', '8.7200', '7.7399'] avg: 8.9886 seconds. Result: 2024 | |
- Version_4. Time: ['11.9411', '11.7733', '11.8226', '11.7166', '11.9001', '11.7232', '11.7850', '11.8588'] avg: 11.8151 seconds. Result: 2024 | |
- Version_5. Time: ['19.3780', '17.8619', '18.0036', '18.1159', '17.9091', '17.9927', '17.9564', '17.9369'] avg: 18.1443 seconds. Result: 2024 | |
- Version_6. Time: ['7.5048', '7.3104', '7.3142', '7.3944', '7.3068', '7.5241', '7.3036', '7.3219'] avg: 7.3725 seconds. Result: 2024 | |
""" |
Немає коментарів:
Дописати коментар