为什么 Cython 类比 Python 数据类慢

问题描述 投票:0回答:1

这是我的 Cython 数据类:

cdef class BookL1:
    cdef readonly str exchange
    cdef readonly str symbol
    cdef readonly double bid
    cdef readonly double ask
    cdef readonly double bid_size
    cdef readonly double ask_size

    def __init__(self, str exchange, str symbol, double bid, double ask, double bid_size, double ask_size):
        self.exchange = exchange
        self.symbol = symbol
        self.bid = bid
        self.ask = ask
        self.bid_size = bid_size
        self.ask_size = ask_size

这是我的 Python 数据类:

from dataclasses import dataclass

@dataclass(slots=True)
class BookL1:
    exchange: str
    symbol: str
    bid: float
    ask: float
    bid_size: float
    ask_size: float

我比较它们的创建和访问时间如下:

from trade_types import BookL1 as CBookL1
from utils import BookL1
import timeit

def create_book_l1():
    return BookL1("binance", "BTC/USDT", 30000.0, 30001.0, 1.5, 2.0)

def create_cbook_l1():
    return CBookL1("binance", "BTC/USDT", 30000.0, 30001.0, 1.5, 2.0)

def access_book_l1(book):
    return (book.exchange, book.symbol, book.bid, book.ask, book.bid_size, book.ask_size)

def run_benchmark(class_type, create_func, iterations=1000000):
    creation_time = timeit.timeit(create_func, number=iterations)
    
    instance = create_func()
    access_time = timeit.timeit(lambda: access_book_l1(instance), number=iterations)
    
    print(f"{class_type} Benchmark Results:")
    print(f"Creation time: {creation_time:.6f} seconds")
    print(f"Access time:   {access_time:.6f} seconds")
    print()

if __name__ == "__main__":
    run_benchmark("Python BookL1", create_book_l1)
    run_benchmark("Cython CBookL1", create_cbook_l1)

我正在使用 Apple M3 芯片在 macOS 14.6.1 上进行测试。这是我的结果:

Python BookL1 Benchmark Results:
Creation time: 0.200142 seconds
Access time:   0.105723 seconds

Cython CBookL1 Benchmark Results:
Creation time: 0.064651 seconds
Access time:   0.169590 seconds

为什么 Cython 访问时间较慢,如何修复?您可以在 cdef-test

中找到我的结果
python cython
1个回答
0
投票

在 Cython 版本中,每次访问

cdef readonly double bid
都需要创建一个新的 Python
float
对象。

在 Python 版本中,

bid
已经作为 Python
float
对象存在,因此这是一个非常非常便宜的查找。

Cython 版本将更小(至少当您考虑类及其指向的所有对象的总大小时),并且从 Cython 访问速度更快。 从 Python 访问 Python 版本将更快因为它不需要拳击 C 类型。

© www.soinside.com 2019 - 2024. All rights reserved.