我正在解决SPOJ问题,INTEST。目标是指定测试用例的数量(n)和除数(k),然后为程序提供n个数字。该程序将接受stdin换行符上的每个数字,并在收到第n个数字后,将告诉您有多少可被k整除。
此问题的唯一挑战是让您的代码更快,因为k
可以是最多10 ^ 7而n
可以高达10 ^ 9。
我正在尝试用Python编写它并且无法加速它。有什么想法吗?
编辑2:我终于在10.54秒时通过了它。我几乎把你所有的答案用到了那里,因此很难选择一个“正确”,但我相信我选择的那个总结得最好。谢谢大家。最终传递代码如下。
编辑:我在附带的代码中包含了一些建议的更新。
不允许使用扩展程序和第三方模块。代码也由SPOJ评判机器运行,因此我无法更改解释器。
import sys
import psyco
psyco.full()
def main():
from sys import stdin, stdout
first_in = stdin.readline()
thing = first_in.split()
n = int(thing[0])
k = int(thing[1])
total = 0
list = stdin.readlines()
for item in list:
if int(item) % k == 0:
total += 1
stdout.write(str(total) + "\n")
if __name__ == "__main__":
main()
答案 0 :(得分:14)
[编辑反映新发现并在代码上传递代码]
通常,在使用Python进行欺骗时:
使用(部分)这些指导原则,我设法通过了INTEST。但仍在测试替代品。
答案 1 :(得分:8)
最后一个是有所作为的。我认为它与变量可见性有关,但我不完全确定。我的时间是10.81秒。你可以通过列表理解来加快速度。
编辑:
使用列表理解将我的时间缩短到8.23秒。将函数内部的from sys import stdin, stdout
行稍微削减,以便将时间缩短到8.12秒。
答案 2 :(得分:6)
使用psyco,它会JIT你的代码,当有大循环和计算时非常有效。
修改:看起来不允许使用第三方模块,
所以,你可以尝试将你的循环转换为列表推导,它应该在C级运行,所以它应该更快一点。
sum(1 if int(line) % k == 0 else 0 for line in sys.stdin)
答案 3 :(得分:3)
就在最近Alex Martinelli说在函数内调用代码,胜过模块中运行的代码(我找不到帖子)
那么,你为什么不试试呢?
import sys
import psyco
psyco.full1()
def main():
first_in = raw_input()
thing = first_in.split()
n = int(thing[0])
k = int(thing[1])
total = 0
i = 0
total = sum(1 if int(line) % k == 0 else 0 for line in sys.stdin)
print total
if __name__ == "__main__":
main()
IIRC原因是函数内部的代码可以被优化。
答案 4 :(得分:3)
使用精神上的列表理解会适得其反。
此代码:
count = 0
for l in sys.stdin:
count += not int(l)%k
的运行速度是
的两倍count = sum(not int(l)%k for l in sys.stdin)
使用心理学时。
答案 5 :(得分:2)
对于其他读者,here is the INTEST problem statement。它旨在进行I / O吞吐量测试。
在我的系统上,通过使用以下代码替换循环,我可以节省15%的执行时间:
print sum(1 for line in sys.stdin if int(line) % k == 0)