MYCSS

2024-11-23

Optimizing Performance: Python Speed Test for Digit Search in Strings

Не так давно я натрапив на пост, де порівнювались різні методи коду для пошуку цифр у рядках у 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
"""


Немає коментарів:

Коли забув ти рідну мову, біднієш духом ти щодня...
When you forgot your native language you would become a poor at spirit every day ...

Д.Білоус / D.Bilous
Рабів до раю не пускають. Будь вільним!

ipv6 ready