极大地热衷于输入python(也许使用Cython)

时间:2020-04-24 14:28:52

标签: python cython

我有一些带有大量类型注释的Python代码,这些类本质上是荣耀的结构(下面的属性是我的类中唯一的方法),并且需要快速运行它。

@dataclass
class Family:
    """A family group agent."""
    descendence: str
    culture: int
    location_history: List[h3.c_int] = field(default_factory=list)
    @property
    def location(self) -> h3.c_int:
        return self.location_history[0]
    number_offspring: int = 0
    effective_size: int = 2
    stored_resources: float = 130000.0
    seasons_till_next_child: int = 4
    seasons_till_next_mutation: Optional[int] = None

@dataclass
class Patch:
    """A patch of land with resources."""
    resources: float
    max_resources: float

例如,我有一个agents: List[Tuple[Patch, Sequence[Family]]](有点复杂,但这与询问原理无关紧要)和这两个函数

def extract_resources(
        patch: Patch, group: Sequence[Family], total_labor_here: int) -> kcal:
    """Distribute the resources gained from cooperative extraction."""
    labor = sum([family.effective_size
                 for family in group])
    resources_extracted = resources_from_patch(
        patch, labor, total_labor_here - labor)
    for family in group:
        family.stored_resources += (
            resources_extracted * family.effective_size / labor)
    return resources_extracted

def resources_from_patch(
        patch: Patch,
        labor: int,
        others_labor: int,
        estimate: bool = False) -> float:
    """Compute or estimate the resources a cooperative gains from a patch."""
    my_relative_returns = (
        time_step_energy_use * labor *
        effective_labor_through_cooperation(labor))
    if not estimate:
        my_relative_returns = numpy.maximum(
            random.gauss(
                mu=my_relative_returns,
                sigma=(params.payoff_standarddeviation *
                       time_step_energy_use / labor ** 0.5)),
            0)
    if others_labor:
        others_relative_returns = (
            time_step_energy_use * others_labor *
            effective_labor_through_cooperation(others_labor))
        if not estimate:
            others_relative_returns = numpy.maximum(
                random.gauss(
                    mu=others_relative_returns,
                    sigma=(params.payoff_standarddeviation *
                           time_step_energy_use / others_labor ** 0.5)),
                0)
    else:
        others_relative_returns = 0
    return (my_relative_returns) / (
        my_relative_returns + others_relative_returns) * min(
            my_relative_returns + others_relative_returns,
            patch.resources * params.accessible_resources)

我要执行

for patch, families in agents:
    extract_resources(patch, families, sum(family.effective_size for family in families))

尽快(包括对每个补丁并行执行extract_resources,保证它们不会相互作用)。

我想将其保留为可由python解释,由mypy和python linters检查的东西。我以为Cython的纯python模式可以帮助我实现这一目标,但是我不理解如何修改这些源代码以在这些约束下以最快的方式在Cython中运行。我看过numba,但是我没有找到一种方法来观察我的带类型注释的类结构类。

我应该使用什么类型的注释,修饰符和次要重构来以最快的并行非GIL限制方式运行这种样式的Python代码?

0 个答案:

没有答案