使用cython加速python应用程序

2024-06-16 15:09:39 发布

您现在位置:Python中文网/ 问答频道 /正文

我在Kivy应用程序中使用以下python代码。 代码工作正常,显示了正确的信息,但是在计算返回值和显示到屏幕上时速度非常慢。 我的问题是:

  1. 我可以用C语言编写这个函数并使用cython将它合并到python程序中吗。

  2. 如果可以的话,会不会有明显的速度提升,或者问题出在其他地方?

def offset_back(initial_bet, initial_odds):

    returns = []
    new_odds = Decimal(initial_odds)
    while new_odds > 1:
        # calculate tick based on size of odds
        if 50 < new_odds <= 100:
            tick = Decimal("5.0")
        elif 30 < new_odds <= 50:
            tick = Decimal("2.0")
        elif 20 < new_odds <= 30:
            tick = Decimal("1.0")
        elif 10 < new_odds <= 20:
            tick = Decimal("0.5")
        elif 6 < new_odds <= 10:
            tick = Decimal("0.2")
        elif 4 < new_odds <= 6:
            tick = Decimal("0.1")
        elif 3 < new_odds <= 4:
            tick = Decimal(".05")
        elif 2 < new_odds <= 3:
            tick = Decimal(".02")
        elif new_odds <= 2:
            tick = Decimal(".01")
        else:
                tick = Decimal("10")

        #  calculate percentage difference between initial bet and new odds
        drop = Decimal(100 - (100 * Decimal(initial_odds) / Decimal(new_odds))) / 100
        # calculate amount needed to increase bet by to cancel liability
        increase = abs((initial_bet * drop))
        # calculate new stake
        new_bet = (initial_bet + increase)
        # calculate potential profit based on the new stake - initial invested stake
        profit = (new_bet - initial_bet)
        returns.append(" Stake: %.2f" % abs(new_bet)+ " " * spacing + "Odds: " "%.2f" % abs(new_odds)+ " " * spacing + "Profit: " "%.2f" % abs(profit))
        new_odds -= tick
    return returns

Tags: 代码newabs速度initialreturnsdecimalcalculate
2条回答

第一个建议:

这里有一些建议,试着把Decimal声明移出循环,只是在加/减时引用它们。只要你创造了一次,它应该快得多。在

decimals = [
 Decimal("10")
 ,Decimal("5.0")
 ,Decimal("2.0")
 ,Decimal("1.0")
 ,Decimal("0.5")
 ,Decimal("0.2")
 ,Decimal("0.1")
 ,Decimal(".05")
 ,Decimal(".02")
 ,Decimal(".01")
]

把if替换成这样:

^{pr2}$

第二个建议:

是删除if else if ...,因为你不总是进入第一个if,你必须做更多的比较才能得到正确的情况。将if块替换为类似的内容。在

thick = decimals[getThick(new_odds)]

getThick应该实现一个可以转换为索引的公式。我想你的厚函数可以用数学来表达。在

这里使用bisect_left是一个不错的主意,除非你能想出一个通过计算实现的函数。在

第三个建议:

用格式字符串替换该行:

returns.append(" Stake: %.2f %s Odds: %.2f %s Profit: %.2f" % 
               (abs(new_bet), spacing, abs(new_odds), spacing, abs(profit)))
  1. 避免使用十进制-你在这里所做的一切都不需要绝对的精度。

  2. 转换if..然后使用bisect

    级联为二进制查找
  3. 我不太明白你的数学到底能完成什么,但我对你在这里使用abs()的用法持怀疑态度。你确定这就是你想要的吗?

  4. 这可能不是一个好主意,但是为了演示:我使用yield语句将函数转换为生成器函数;它不是返回字符串数组,而是一次返回一个字符串。

一。在

from bisect import bisect_left

breakpoints = [-1.,  2.,   3.,   4.,   6.,   10.,  20.,  30.,  50.,  100.]
ticks       = [0.,   0.01, 0.02, 0.05, 0.1,  0.2,  0.5,  1.,   2.,   5.,   10.]

def offset_back(initial_bet, initial_odds, breakpoints=breakpoints, ticks=ticks):
    new_odds = initial_odds
    while new_odds > 1.:
        # calculate tick based on size of odds
        tick = ticks[bisect_left(breakpoints, new_odds)]
        # calculate percentage difference between initial bet and new odds
        drop = 1. - initial_odds / new_odds
        # calculate new stake, increased to cancel liability
        new_bet = initial_bet + abs(initial_bet * drop)   # are you sure abs() is correct here?
        # calculate potential profit based on the new stake - initial invested stake
        profit = new_bet - initial_bet

        new_odds -= tick
        yield " Stake: {stake:0.2f}    Odds: {odds:0.2f}    Profit: {profit:0.2f}".format(stake=abs(new_bet), odds=abs(new_odds), profit=abs(profit))

相关问题 更多 >