【问题标题】:How come these Python codes perform so much differently为什么这些 Python 代码的表现如此不同
【发布时间】:2013-02-23 13:26:16
【问题描述】:

请查看以下代码来解决同一组问题,我认为提及问题无论如何都不会帮助达到目的,这是Josephus problem的又一次迭代:

解决方案 1:

import sys
from math import log

cases= int(sys.stdin.readline())
current= 0
while current < cases:
    current += 1
    n = int(sys.stdin.readline())
    print 2*(n - 2**(int(log(n,2))))+1

此方案在累计 1.0912 秒内解决给定的 10 个测试用例,并消耗 4360KiB 的内存。

解决方案 2:

def josephus_2( n ):
    from math import log
    return 2*(n - 2**(int(log(n,2))))+1

import sys
cases= int(sys.stdin.readline())
current= 0
while current < cases:
    current += 1
    n = int(sys.stdin.readline())
    print josephus_2( n )

此解决方案在总共 1.0497 秒和 640KiB 内存中解决了相同的 10 个测试用例。

作为一名 Python n00b 我想知道,虽然根据在线评委的说法,我在这两个方面都获得了相同的分数,但是是什么让解决方案 2 比 1 更快并且内存效率更高?我知道时差听起来可能非常小,但同时在最快的解决方案上我排名第一,甚至比 c/c++/perl 提交的速度还快

Can this Screenshot help?

【问题讨论】:

  • 有什么方法可以自己测试吗?第一种方法对我来说要快得多。
  • 如果将复杂的函数分离成自己的方法,这可能与 JITing 更容易有关。只是猜测
  • 您有示例输入文件吗?
  • 你试过用dis反编译吗?
  • 检查此stackoverflow.com/questions/11241523/… 生成的字节码因变量范围而异,即本地与全局

标签: python performance python-2.7 time josephus


【解决方案1】:

在我以前的经验中,我记得我发现将计算部分放在函数(方法)中有时可能会提高性能:
我刚刚重新体验了使用以下简单代码:

n = 1000000
def compute(n):
    j = 0
    for i in xrange(n):
        j += 1

tic()
compute(n)
toc()

>>> 0.271 s

tic()
j = 0
for i in xrange(n):
    j += 1
toc()

>>> 0.849 s

结果显示第一个(使用计算)为 0.271 秒,而内联代码为 0.849 秒。这是显着的改进,而无需更改主要计算部分的任何内容! 所以重点是使用一种方法可以提高性能。

以下是您可用于性能比较的代码:

from __future__ import division
from time import clock

def compute(n):
    j = 0
    for i in xrange(n):
        j += 1

n = 1000000
print 'solution (2) using a method call...'
t0 = clock()
compute(n)
print clock()-t0
#>>> ~0.2415...                              #faster (solution 2)

print 'solution (1) all inline code...'
t0 = clock()
j = 0
for i in xrange(n):
    j += 1
print clock()-t0
#>>> ~0.6169...                              #slower (solution 1)

【讨论】:

  • 我认为在我的情况下是相反的...... :)
  • @whizzzkid 但是在你的问题中,第一个解决方案(没有方法)需要 1.0912 秒,而使用方法的第二个解决方案只需要 1.0497 秒。这意味着在您的案例中使用改进的方法可以节省 0.0415 秒。因此,正如我在回答中所解释的,使用方法可以提高性能。不要错过我的回答中第一个是使用方法(即您的第二个解决方案)。
  • 我刚刚使用timeit 尝试了您的代码,两种方法都得到了相同的结果(使用repeat 方法的minrepeat=7, number=10 和适当的stmtsetup 字符串)。
猜你喜欢
  • 2022-01-14
  • 2015-04-04
  • 2012-05-12
  • 1970-01-01
  • 2022-10-15
  • 2014-05-24
  • 1970-01-01
  • 2020-07-23
  • 2011-10-10
相关资源
最近更新 更多