Python полюбляють за його простоту, але він не славиться швидкістю. При виконанні обчислювально інтенсивних завдань його інтерпретований характер може зробити його значно повільнішим за мови нижчого рівня, як C або C++. Тут на допомогу приходить Cython — справжня революція, яка поєднує зручність Python з необробленою продуктивністю C.
У цій статті ми розглянемо основи Cython, покажемо, як почати роботу з ним і продемонструємо, як ви можете прискорити код Python на 10x до 100x і більше з мінімальними зусиллями.
Що таке Cython?
Cython — це мова програмування, яка є оптимізованим надмножиною Python. Вона дозволяє писати код, подібний до Python, але компілює його в розширення C, яке потім можна імпортувати та використовувати в Python. Це дає вам найкраще з обох світів: гнучкість Python і швидкість C.
Коли слід використовувати Cython?
- Числові обчислення: Цикли та обчислення над великими наборами даних.
- Вузькі місця у продуктивності: Оптимізація певних функцій, що займають багато часу.
- Взаємодія з бібліотеками C/C++: Cython спрощує процес використання низькорівневих бібліотек у Python.
Як почати працювати з Cython
Щоб продемонструвати потужність Cython, давайте оптимізуємо просту функцію Python. Ми порівняємо чисту реалізацію на Python з її версією, оптимізованою за допомогою Cython.
Приклад завдання: Обчислити квадрат кожного числа у списку.
Крок 1: Версія на Python
Ось наша реалізація на Python:
def compute_squares(nums list[int]) -> list[int]:
return [x ** 2 for x in nums]
Ця функція добре працює для малих наборів даних, але з великим введенням вона може стати вузьким місцем.
Крок 2: Напишемо код на Cython
Збережіть наступний код у файлі з розширенням .pyx
, який Cython використовує як вихідний файл (наприклад, compute.pyx
):
cpdef compute_squares_cython(double[:] nums):
cdef int i
cdef int n = nums.shape[0]
cdef double[:] result = np.empty(n)
for i in range(n):
result[i] = nums[i] ** 2
return result
Що тут змінено?
cpdef
: Робить функцію доступною як для Python, так і для C.- Типізовані змінні (
cdef
): Оголошення типів (наприклад,int
,double
) для швидшого виконання. - Memoryviews (
[:]
): Використовує ефективний доступ до пам'яті для числових масивів.
Крок 3: Налаштування Cython
Щоб скомпілювати файл .pyx
у C-розширення, вам знадобиться файл setup.py
:
from setuptools import setup
from Cython.Build import cythonize
setup(
ext_modules=cythonize("compute.pyx"),
)
Запустіть наступну команду, щоб зібрати розширення:
python setup.py build_ext --inplace
Це створить файл .so
, який можна імпортувати безпосередньо в Python.
Крок 4: Тестування функції Cython
Тепер використаємо скомпільовану функцію у вашому Python-скрипті:
from compute import compute_squares_cython
nums = [1.0, 2.0, 3.0]
print(compute_squares_cython(nums))
Крок 5: Бенчмаркінг результатів
Щоб побачити покращення швидкості, виміряємо продуктивність за допомогою модуля time
Python:
import time
import numpy as np
nums = np.random.rand(10**6) # Генеруємо 1 мільйон випадкових чисел
# Тестуємо версію на Python
start = time.time()
compute_squares(nums)
print("Версія на Python:", time.time() - start, "секунд")
# Тестуємо версію на Cython
start = time.time()
compute_squares_cython(nums)
print("Версія на Cython:", time.time() - start, "секунд")
Ви, ймовірно, побачите, що версія на Cython працює 10x до 100x швидше за чисту версію на Python.
Чому Cython працює швидше?
- Статична типізація: Змінні з фіксованими типами (наприклад,
int
,double
) дозволяють компілятору оптимізувати обчислення. - Оптимізація циклів: Скомпільовані цикли C в Cython значно ефективніші за інтерпретовані цикли Python.
3.
Зменшення витрат: Функції, скомпільовані за допомогою Cython, уникають витрат на динамічну перевірку типів у Python.
Коли використовувати Cython
Cython не є необхідним для кожного проєкту, але він безцінний, коли:
- Ви працюєте з великими наборами даних або обчислювально інтенсивними завданнями.
- Вам потрібен продуктивний код, але ви хочете уникнути повного переходу на C/C++.
- Ви хочете інтегрувати бібліотеки C/C++ у ваш Python робочий процес.
Поради для ефективного використання Cython
- Почніть з малого: Визначте вузькі місця в продуктивності вашого коду (використовуйте профайлер, наприклад,
cProfile
) і оптимізуйте ці конкретні функції за допомогою Cython. - Використовуйте memoryviews: Для числових даних використовуйте типізовані memoryviews (
[:]
), а не списки Python для швидшого доступу. - Використовуйте наявні бібліотеки: Поєднуйте Cython з бібліотеками, як-от NumPy, для додаткових прискорень.
Підсумки
Cython дає змогу розробникам Python вирішувати завдання, що потребують великої продуктивності, не залишаючи зони комфорту. Незалежно від того, чи ви є дата-сайентистом, дослідником чи розробником, інтеграція Cython у ваші проєкти може забезпечити неймовірне підвищення продуктивності з мінімальними зусиллями.
Тож чому б не почати? Почніть оптимізувати ваш код на Python за допомогою Cython уже сьогодні та відчуйте швидкість скомпільованого C в простоті Python.
Перекладено з: Unlock Python’s True Potential: Speed Up Your Code with Cython