Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/348.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使这个项目解决方案在Python中以与Java相同的速度执行?_Java_Python_Performance - Fatal编程技术网

如何使这个项目解决方案在Python中以与Java相同的速度执行?

如何使这个项目解决方案在Python中以与Java相同的速度执行?,java,python,performance,Java,Python,Performance,在任何人开始之前,我知道在编程语言中谈论“速度”并不总是最重要的。。。有益的讨论。也就是说,速度是这里的问题 我用这两种语言进行了讨论,虽然我用这两种语言的实现看起来与我的眼睛非常相似,但运行时却大不相同。Java只需几秒钟就能返回答案,而Python可能需要一分钟(当然是在同一台机器上)。我很确定这不是Python的错,而是一个程序员(我)的错,他还没有学会用Python来思考 请注意,我不是要求您重写我的代码。我只是在寻找正确方向上的一些推动。(是的,我已经看过了,但其中大部分都是我自己搞不

在任何人开始之前,我知道在编程语言中谈论“速度”并不总是最重要的。。。有益的讨论。也就是说,速度是这里的问题

我用这两种语言进行了讨论,虽然我用这两种语言的实现看起来与我的眼睛非常相似,但运行时却大不相同。Java只需几秒钟就能返回答案,而Python可能需要一分钟(当然是在同一台机器上)。我很确定这不是Python的错,而是一个程序员(我)的错,他还没有学会用Python来思考

请注意,我不是要求您重写我的代码。我只是在寻找正确方向上的一些推动。(是的,我已经看过了,但其中大部分都是我自己搞不清楚的,没有直接比较两种语言中的同一算法。这很有帮助,但也没有直接比较Java和Python——坦白说,答案有点难理解。)

不言而喻:

JAVA python
有趣的是,并排阅读这些内容,我已经看到Python版本的算法比Java版本稍微优化了一些,但仍然慢得多。我现在更想找到另一种方法来解决这个问题。

我不确定这会有多大帮助,但您的工作者代码可以用一种更为通俗的方式重写,如下所示:

def divis_through_twenty(n):
  return any(n % x for x in xrange(20,1,-1))

x = 20
while divis_through_twenty(x):
  x += 20

print x

如果您愿意,您可以对它进行更多的优化(例如,如果您已经测试了一个数字可以被20整除,那么您不需要检查它是否可以被10、5或2整除)

Python是一种动态类型语言,而Java是一种静态类型语言。这意味着Java在编译时有更多关于变量类型的可用信息,特别是数字。Java的设计者花了相当多的精力定义JVM,使32位(
int
)和64位算术(
long
)计算能够高效地工作

另一方面,Python没有变量类型声明,因此
x
等变量可以保存任何对象。在您的例子中,它们总是包含数字,但是CPython的编译器没有进行验证。Python执行代码时,计算表达式(如
number%x
)需要查找
number
表示的对象的
%
运算符,调用
%
运算符,获取
x
的类型,确保它是兼容的数字类型,等等。这一切都需要时间,特别是当你做了无数次的时候

PyPy之类的替代Python实现会尽最大努力确定变量的类型。在您的情况下,它可以确定
number
x
始终引用整数,并生成不必检查类型的适当低级代码


最后,您可能希望查找以任何语言解决此Project Euler问题的更快方法。与Project Euler问题一样,最快的解决方案不是通过编写更快的代码,而是通过选择合适的算法。

我怀疑这是一个错误。Python被解释,因此速度较慢。@Chris:Python被编译成虚拟机表示,就像Java一样。然而,Python是动态类型的,Java是静态类型的。这是一个很好的例子,说明了为什么在使用蛮力算法时进行微优化是一个愚蠢的想法:5分钟的思考可以避免数小时的基准测试和试错,并产生更快的代码。尽管我对所有其他的线程都有些震惊,这些线程也没有提到通过素因子分解或其他方法计算lcm的明显解决方案(在这种情况下,python和java之间的差异在我的pc上是无法测量的)@Voo这是一个相当精英化的、毫无帮助的评论。谢谢你假设我事先没有花时间考虑这个问题。你真的认为我知道一个更好的解决方案,只是没有使用它?初学者的特点是不知道自己不知道的东西。除此之外,你的评论是无条件的。我对更快的算法不感兴趣,我感兴趣的是为什么相同的算法在两种不同的语言中有如此不同的运行时。@Zelbinian重要的是要知道,当选择正确的算法时,Java和Python等优化的优势不会消失。寻找正确的算法是Pythonic;手动优化错误的算法是不正确的。我欣赏的洞察力。但是,这并不能帮助我学习如何以更“Pythonic”的方式编写代码的第二部分,因此我选择了另一个答案。@Zelbinian:wim实现的性能与您的相比如何?在我的机器上,它需要27秒,而你的需要18秒。更小、更“pythonic”的代码并不一定意味着更快的代码。虽然学习如何使我的Python代码“Pythonic”也是这里的一个目标。@GregHewgill你的计时很有趣-你对为什么会这样有什么评论?我假设生成器表达式和
any
将以与OP的
返回相同的方式短路。虽然我删除了逻辑中的双重否定,但这不应该改变计时。那么慢度是从哪里来的呢???@wim:我想这是
any(…)
中生成器表达式调用的回调次数。OP问题中的显式循环避免了每次迭代调用生成器表达式。谢谢-这正是我需要的。让我仔细思考一下你的代码和我的代码之间的差异——我相信我会有更多的问题!不客气,开火吧。我也刚刚想到,既然你是以20的倍数递增测试数,你甚至不需要检查20的整除性(和10,5,2)。但这有点离题。。和其他人一样
def DivisThroughTwenty(number):
    for x in range(20,1,-1):
        if number % x != 0:
            return False
    return True

# the number we're looking for can't be any lower than 20, so we'll
# start there as a small optimization
testNumber = 20

keepLooking = True

while keepLooking:
    if not DivisThroughTwenty(testNumber):
        testNumber += 20
    else:
        keepLooking = False

print testNumber
def divis_through_twenty(n):
  return any(n % x for x in xrange(20,1,-1))

x = 20
while divis_through_twenty(x):
  x += 20

print x