Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/328.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
Java和Python实现的速度_Java_Python_Performance_Big O - Fatal编程技术网

Java和Python实现的速度

Java和Python实现的速度,java,python,performance,big-o,Java,Python,Performance,Big O,所以我有一个问题,我已经用python和java解决了。问题是,对于8000*8000个元素的乘法表,找到所有唯一的数字: Python: table = 8000 unique_prods = [] start = 1 for i in range(table*table + 1): unique_prods.append(0) for x in range(1, table + 1): for y in range(start, table + 1): #

所以我有一个问题,我已经用python和java解决了。问题是,对于8000*8000个元素的乘法表,找到所有唯一的数字:

Python:

table = 8000
unique_prods = []
start = 1

for i in range(table*table + 1):
    unique_prods.append(0)

for x in range(1, table + 1):
    for y in range(start, table + 1):
        # print '{:4}'.format(x * y),
        if not unique_prods[x * y] == x * y:
            unique_prods[x * y] = x * y
    start += 1
    # print

# print unique_prods
print len(unique_prods)
爪哇:

公共类测试{
公共静态void main(字符串[]args){
int table=8000;
int[]myArray=newint[table*table+1];
整数计数=1;
对于(int i=0;i

我发现Java实现只花了一秒钟,Python版本只花了一分钟,这让我感到惊讶。有没有办法提高python的性能,使其更接近Java实现的速度?

您的python代码不是最优的,您不会像在Java中那样解决问题:

table = 8000
unique_prods = set()

for x in range(1, table + 1):
    for y in range(x, table + 1):
        unique_prods.add(x * y)
print len(unique_prods)
在我的电脑上显示14秒。 但很明显,python仅仅解决数学问题需要更长的时间,因为python没有集成的JIT编译器。对于计算,有一个名为numpy的包,它可以显著加快速度:

import numpy
x = numpy.arange(1,8001)
unique_prods = numpy.zeros(8000*8000+1,dtype='b')
for k in x:
    unique_prods[k*x[k-1:]]=1
print unique_prods.sum()

你只需要0.8秒就能得到结果。与C版本相比,它只需要0.6s。

Python可能会比较慢,但是考虑下面两个片段:更多的PythOng:< /P>
import time 
starttime = time.time()
table = 8000
unique_prods = [0] * (table*table + 1)
for x in range(1, table+1):
    for y in range(1, table+1):
        unique_prods[x*y] = 1

elapsed = time.time() - starttime
print((elapsed, sum(unique_prods)))
最简单但不一定是最快的:

starttime = time.time()
table = 8000
unique = set(x*y for x in range(1, table+1) for y in range(1,table+1))
elapsed = time.time() - starttime
print((elapsed, len(unique)))
Python并不是设计得最快的。python的优点是您可以编写

unique = set(x*y for x in range(1, table+1) for y in range(1,table+1))
print(len(unique))

基本上是一个一行程序,它清楚地解决了基本的数学问题,即定义一个集合并打印它的基数。

问题似乎在于如何用python创建数组

考虑以下几点:

array = []

for i in range(8000*8000 + 1):
  array.append(0)
这花了很长时间运行(对我来说是14秒),因为我们首先创建了一个空数组,然后总共调整了64000001次大小。您不应该这样做,而是应该创建一个大小正确的数组,以便只需要一次内存分配:

array = [0] * (8000*8000 + 1) // Creates an array filled with zeros of size (8000*8000 + 1)

这段代码对我来说几乎是即时运行的。

正如其他人所注意到的,扩展列表的方式有利于此算法的Java实现。这是一个简单的解决方案:

unique_prods = [0] * (table*table + 1)
生成您的算法的以下结果(实现与您发布的完全相同):



另外,您的两个实现都是错误的(您应该使用一个集合),并且还有其他一些小的错误(比如注释中提到的冗余
if
语句)。

哦,我现在看到Python会给出错误的答案,但这可以通过遍历列表轻松修复。很抱歉。为什么要先检查
myArray[x*y]
是否不等于
x*y
,然后再将其设置为
x*y
?如果它已经相等,则将其设置为自身相等不会更改其值。如果它还不相等,则将设置为
x*y
if
是多余的。
对于范围内的i(表*table+1):unique_prods.append(0)
应该替换为
unique_prods=[0]*(表*table+1)
,这在我的机器上要快15倍。要想获得关于工作代码的反馈,最好是询问CodeReview.SE。@curiousinternal是的,我完全误解了,现在我看到了,这很明显。我看到有人说我应该在代码回顾中发表这篇文章,但我认为这是一个非常重要的问题,因为我们正在比较两种方法,看看算法的复杂性,看看是否可以通过讨论来改进。我认为这类问题属于这里的SO。显然,Java版本也应该使用set方法。所以这没有意义。要么比较两个最优实现,要么比较两个非最优实现。声称Python在这方面与Java不同是错误的。在我的计算机上,Python中的set方法比使用长度表*表的列表更简单,但速度要慢得多。这真的很快。你能解释一下你在做什么吗。我无法理解行unique_prods[k*x[k-1:][]=1您是否尝试过将整个程序与之进行比较,而没有此修复程序?@BartoszKP我刚刚进行了比较,结果显示我的第一次测试给出了非常不准确的结果。我不知道为什么第一次用了一分钟而不是14秒(后台运行的东西?),但我想这会教我做重复测试。回到绘图板上…Python有
timeit
模块用于此目的。使用
timeit
可以更可靠地比较实现。与另一个答案一样:在与另一个实现进行比较时,仅在一个实现中更改基础算法是没有意义的。@BartoszKP:我在比较任何东西,只是展示了一些选项。这个问题与Python和Java之间的比较有关。
unique_prods = [0] * (table*table + 1)
python -m timeit -n 10 -r 1 "import test" "test.testWithFix()"
64000001
64000001
64000001
64000001
64000001
64000001
64000001
64000001
64000001
64000001
10 loops, best of 1: 31.6 sec per loop
python -m timeit -n 10 -r 1 "import test" "test.testWithoutFix()"
64000001
64000001
64000001
64000001
64000001
64000001
64000001
64000001
64000001
64000001
10 loops, best of 1: 62.9 sec per loop