微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Python 类型注释减慢代码

如何解决Python 类型注释减慢代码

我正在优化我的代码以提高性能,当我使用 cProfile 检查我的代码时,大量的运行时是由于类型注释!删除类型注释确实提高了性能。您可以在下面看到带注释和未注释的 cProfiler输出

注释代码

Annotated code performance

未注释的代码

Performance of the code without annotation

注释中明确使用了__call____new__inner__getitem____hash__typing.py中的方法,并且是比未注释的慢两倍!

我的测试代码很简单:

from reil.datatypes import reildata

x = reildata.Categorical(name='cat',categories=('A','B','C','D','E'))

for _ in range(10000):
    [x(v) for v in ('A','E')]

这是主要代码的相关部分(datatypes.reildata.py):

from __future__ import annotations

import dataclasses
import itertools
from dataclasses import field
from typing import Any,Callable,Dict,Generic,Iterable,Iterator,List,Optional,Sequence,Tuple,TypeVar,Union,cast

from typing_extensions import Literal


T = TypeVar('T')

CategoricalType = TypeVar('CategoricalType')

normal = Union[Literal[0],Literal[1],float]
normalized = Union[normal,Tuple[normal,...],None]


@dataclasses.dataclass(frozen=True)
class ReilSingleton(Generic[T]):
    name: str
    value: Optional[Union[T,Tuple[T,...]]] = None
    is_numerical: Optional[bool] = field(
        repr=False,compare=False,default=None)
    normalized: normalized = field(
        default=None,repr=False,compare=False)


@dataclasses.dataclass(frozen=True)
class Categorical(Generic[CategoricalType]):
    name: str
    categories: Optional[Tuple[CategoricalType,...]] = None
    normal_form: Optional[Dict[CategoricalType,...]]] = field(
        default=None,init=False,compare=False)

    def __post_init__(self):
        if self.categories is None:
            return

        cat_count = len(self.categories)
        normal_form = {}
        for i,c in enumerate(self.categories):
            temp = [0] * cat_count
            temp[i] = 1
            normal_form[c] = tuple(temp)

        self.__dict__['normal_form'] = normal_form

    def __call__(self,data: Union[CategoricalType,Tuple[CategoricalType,...]]
                 ) -> ReilSingleton:
        normal_form = self.normal_form
        categories = cast(Tuple[CategoricalType,self.categories)

        if normal_form is None:
            normalized = None
        elif data in categories:
            normalized = normal_form[cast(CategoricalType,data)]
        else:
            try:
                normalized = tuple(
                    itertools.chain(
                        *(normal_form[d]
                          for d in cast(Tuple[CategoricalType,data))))
            except KeyError:
                raise ValueError(
                    f'{data} is not '
                    f'in the categories={categories}.')

        instance = ReilSingleton[CategoricalType](
            name=self.name,is_numerical=False,value=data,normalized=normalized)
        instance.__dict__['categories'] = categories
        instance.__dict__['dict_fields'] = ('name','value','categories')

        return instance

如果我想保留注释怎么办?难道我做错了什么?我的 Python 解释器是 Python 3.7.8 (cpython),我在 Windows 10 上运行测试。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。