为什么这个算法在python中的运行速度比在C ++中快得多?

时间:2016-02-06 18:17:18

标签: python c++ algorithm

我正在阅读" C ++中的算法"由Robert Sedgewick和我进行了这个练习:用另一种编程语言中的算法减半,用路径压缩重写这个权重的快速联合。

该算法用于检查是否连接了两个对象,例如,对于像1 - 2,2 - 3和1 - 3这样的条目,前两个条目创建新连接,而在第三个条目中,1和3已连接,因为3可以从1:1 - 2 - 3到达,因此第三个条目不需要创建新连接。

很抱歉,如果算法描述不可理解,那么英语不是我母亲的语言。

所以这是算法本身:

#include <iostream>
#include <ctime>

using namespace std;

static const int N {100000};

int main()
{
    srand(time(NULL));

    int i; 
    int j; 

    int id[N];  
    int sz[N]; // Stores tree sizes

    int Ncount{}; // Counts the numbeer of new connections 
    int Mcount{}; // Counts the number of all attempted connections

    for (i = 0; i < N; i++)
    {
        id[i] = i;
        sz[i] = 1;
    }

    while (Ncount < N - 1)
    {
        i = rand() % N;
        j = rand() % N;

        for (; i != id[i]; i = id[i])
            id[i] = id[id[i]];

        for (; j != id[j]; j = id[j])
            id[j] = id[id[j]];

        Mcount++;

        if (i == j) // Checks if i and j are connected 
            continue;

        if (sz[i] < sz[j]) // Smaller tree will be 
                           // connected to a bigger one 
        {
            id[i] = j;
            sz[j] += sz[i];
        }
        else
        {
            id[j] = i;
            sz[i] += sz[j];
        }

        Ncount++;
    }

    cout << "Mcount: " << Mcount << endl;
    cout << "Ncount: " << Ncount << endl;

    return 0;
}

我知道一点点蟒蛇,所以我选择它进行这项练习。这是得到的:

import random

N = 100000

idList = list(range(0, N))
sz = [1] * N

Ncount = 0
Mcount = 0

while Ncount < N - 1:

    i = random.randrange(0, N)
    j = random.randrange(0, N)

    while i is not idList[i]:
        idList[i] = idList[idList[i]]
        i = idList[i]

    while j is not idList[j]:
        idList[j] = idList[idList[j]]
        j = idList[j]

    Mcount += 1

    if i is j:
        continue

    if sz[i] < sz[j]:
        idList[i] = j
        sz[j] += sz[i]
    else:
        idList[j] = i
        sz[i] += sz[j]

    Ncount += 1

print("Mcount: ", Mcount)
print("Ncount: ", Ncount)  

但是我偶然发现了这个有趣的细微差别:当我将N设置为100000或更多时,C ++版本似乎比python版本慢很多 - 在python中完成任务的时间大约需要10秒而C ++版本这样做很慢,我不得不关闭它。

所以我的问题是:原因是什么?这是否因为rand()%N和random.randrange(0,N)的不同而发生?或者我刚做错了什么?

如果有人能够向我解释这一点,我将非常感激,提前谢谢!

2 个答案:

答案 0 :(得分:3)

这些代码做了不同的事情。

您必须将python中的数字与==进行比较。

>>> x=100000
>>> y=100000
>>> x is y
False

可能还有其他问题,无法检查。您是否比较了应用程序的结果?

答案 1 :(得分:2)

如上所述,代码并不相同,特别是在使用is vs ==时。

查看以下Pyhton代码:

while i is not idList[i]:
    idList[i] = idList[idList[i]]
    i = idList[i]

评估 0或1次。为什么?。因为如果while第一次评估为True,那么i = idList[i]会在第二次传递中生成条件True,因为现在i肯定是一个数字在is

idList

等效c++

for (; i != id[i]; i = id[i])
     id[i] = id[id[i]];

此处代码检查相等而非存在,并且运行它的次数不固定为 0或1

所以是的...使用is vs ==会产生巨大差异,因为在Python中您正在测试实例相等包含在中,而不是在等价的意义上测试简单的相等

上面的Python和C ++的比较就像比较苹果和梨。

注意:问题的简短答案是: Python版本的运行速度要快得多,因为它比C ++版本要少得多