【发布时间】:2021-06-22 15:39:49
【问题描述】:
所以我目前正在参加 google Foobar Challenge,结果发现最新的是 Python 2.7 而不是 3.8。我没有读到这个,真丢脸,所以我在 3.8 中开发,现在遇到了一些我不确定它们来自哪里的异常。我已经发现整数和浮点除法之间可能存在差异,但我不知道这是否真的是我问题的根源。 (顺便说一句,我不能使用 from_future_)
进入代码:
import math
from math import gcd
def findmultiples(coordinates, list, dim):
coords = coordinates[:]
while (coordinates[0] <= dim[0] and coordinates[1] <= dim[1]) and (coordinates[0] >= -dim[0] and coordinates[1] >= -dim[1]):
if tuple(coordinates) in list:
list.remove(tuple(coordinates))
coordinates[0] = coordinates[0] + coords[0]
coordinates[1] = coordinates[1] + coords[1]
return list
def solution(dim, your_position, trainer_position, distance):
coordinate = [(x,y) for x in range(-dim[0] , dim[0]+1) for y in range(-dim[1] , dim[1]+1)]
coordinate.sort()
result = []
for i in range(1):
for x,y in coordinate:
y_position = your_position[:]
t_position = trainer_position[:]
beam_position = your_position[:]
distancetraveled = 0
if x == 0 and y == 0:
continue
denom = gcd(x,y)
x = x/denom
y = y/denom
while True:
distancetraveled += math.sqrt((x * x) + (y * y))
if(distancetraveled > distance):
break
beam_position[0] += x # add x coordinate
beam_position[1] += y
if (beam_position[0] > dim[0] or beam_position[0] <0 ): # Check if out of bounds along x-axis
t_position[0] = dim[0] - t_position[0] # Mirror the t_position along the y-axis
y_position[0] = dim[0] - y_position[0] # Mirror y_position along the y-axis
beam_position[0] = (beam_position[0] + dim[0]) % (2*dim[0])
if (beam_position[1] > dim[1] or beam_position[1] <0 ): # Check if out of bonds along y-axis
t_position[1] = dim[1] - t_position[1] # Mirror the t_position along the x-axis
y_position[1] = dim[1] - y_position[1] # Mirror y_position along the x-axis
beam_position[1] = (beam_position[1] + dim[1]) % (2*dim[1])
if (beam_position[0] == t_position[0] and beam_position[1] == t_position[1]):
coordinate = findmultiples([x,y], coordinate, dim)
count = 1
result.extend((x,0) for x in range(count))
break
if(beam_position == y_position):
coordinate = findmultiples([x,y], coordinate, dim)
break
return len(result)
它相当短,为了能够在 Python 2.7 上运行它,我必须做的唯一区别(至少我是这么认为的)是将第二个导入更改为 from fractions import gcd 但显然这不起作用,至于一些程序永远在第 10 行运行的原因 coordinates[0] = coordinates[0] + coords[0]。到目前为止,我无法完成我正在运行的 cProfile 测试,所以我目前假设程序被卡在那里。
现在我可以观察到的差异(因为程序完成)是solution([3,2], [1,1], [2,1], 4),结果在 Python 2.7 中返回为 7(正确的结果顺便说一句),在 3.9 中返回为 6。使用solution([300,275], [150,150], [185,100], 500) 进行的第二次测试尚未完成。我尝试使用 cProfile 测量时间,但第一次测试完成得太快,以至于我看不到任何有用的东西。 (0.000s vs 0.001s)
我尝试在谷歌上搜索,但没有深入研究 Python 2.7.13 文档的 6.5k 页,我只能找到不同之处。
我希望有人可以帮助我。干杯
编辑:cProfile 实际上完成了,但没有告诉我很多(编辑:它确实告诉我 findmultiples 在这个版本中被称为比在其他版本中更多:
ncalls tottime percall cumtime percall filename:lineno(function)
1 3.905 3.905 1417.093 1417.093 4.1.py:16(solution)
689 1408.263 2.044 1412.459 2.050 4.1.py:5(findmultiples)
26 0.000 0.000 0.000 0.000 4.1.py:51(<genexpr>)
1 0.012 0.012 1417.105 1417.105 <string>:1(<module>)
330463 0.208 0.000 0.208 0.000 fractions.py:18(gcd)
1 0.000 0.000 0.000 0.000 {len}
3638301 0.499 0.000 0.499 0.000 {math.sqrt}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
13 0.000 0.000 0.000 0.000 {method 'extend' of 'list' objects}
687 4.197 0.006 4.197 0.006 {method 'remove' of 'list' objects}
1 0.015 0.015 0.015 0.015 {method 'sort' of 'list' objects}
616 0.007 0.000 0.007 0.000 {range}
它花费的时间是 Python 3.8 的近 40 倍。 1417s 与 37s 的主要区别在于 find multiples 被调用的频率大约是 30 倍。这将解释差异的冲击。 我能够找到问题(至少我认为我做到了)。出于某种原因,list.remove() 和 gcd() 函数的工作方式有些不同。我把它们改成了这样:
index = list.index(tuple(coordinates))
list.pop(index)
list.insert(index, (0,0))
.
.
.
.
denom = gcd(x,y)
x = x/abs(denom)
y = y/abs(denom)
现在代码在 Python3.x 和 Python 2.x 中的工作方式似乎相同。有趣的是,在 2.x 中它现在快了大约 20%,但我懒得去弄清楚为什么
【问题讨论】:
-
这不正是我写的吗? '是将第二个导入更改为“从分数导入 gcd”,但显然这是'但我可以将其更改为代码 sn-p
-
对不起,我错过了你放在正文中的便条。我期待代码 sn-p 是 python2
-
“十多年前,不受支持的运行时比现代版本慢,新闻在 11”。这里的实际问题是什么?
-
“2016 年发布”,但仅对 2010 年发布的版本进行了安全性和正确性修复——性能优化通常不会进入点发布,其想法是保守的.
-
无论如何——我建议标题是关于结果差异的,而不是运行时的差异,如果那是你真正想要调查的(并且运行时差异是次要的)。然而,如果运行时问题是您要问的主要问题,我不确定这个问题是否完全符合主题(我们在这里是为了“实用、可回答”的问题,并且引入了很多小的改进在整个 3.x 中——以及一些大型的,但在没有其他支持因素的情况下,性能增量不太可能有一个真正的答案)
标签: python python-3.x python-2.7