我在Kivy应用程序中使用以下python代码。 代码工作正常并显示正确的信息,但在计算返回值和显示到屏幕时速度很慢。 我的问题是:
我可以用C编写函数并使用cython将它合并到我的python程序中。
如果可以的话,是否会有明显的速度提升或问题出在其他地方?
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
答案 0 :(得分: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:
if 50 < new_odds <= 100:
tick = decimals[1]
第二个建议:
是删除if else 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..then级联转换为使用bisect
的二进制查找
我不清楚你的一些数学知识到底是什么,但我对你在这里使用abs()
非常抱歉。你确定那是你想要的吗?
可能不是一个好主意,但为了演示:我已使用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))