天天看点

为什么c比python快_为什么我在C语言中的计算速度比Python快得多

TL;DR:冗长的文章,是我试图保护Python(我选择的语言)不受C#的攻击。在本例中,C#执行得更好,但仍然需要更多的代码行来完成相同的工作量,但最终的性能优势是,如果正确编码,C#比Python中类似的方法快大约5倍。最终的结果是你应该使用适合你的语言。

当我运行C#示例时,在我的机器上大约花了3秒钟完成,结果是232792560。如果一个数是20的倍数,那么它只能被1到20的数整除,因此不需要增加1,而需要增加20。这一次优化使代码在353毫秒内执行速度提高了约10倍。

当我运行Python示例时,我放弃了等待,尝试使用itertools编写自己的版本,这并没有获得更好的成功,而且花费的时间和您的示例差不多长。然后我找到了一个可以接受的itertools版本,如果我考虑到只有最大数的倍数才能被从最小到最大的所有数整除。因此,精制的Python(3.6)代码在这里提供了一个decorator计时函数,该函数打印执行所需的秒数:import time

from itertools import count, filterfalse

def timer(func):

def wrapper(*args, **kwargs):

start = time.time()

res = func(*args, **kwargs)

print(time.time() - start)

return res

return wrapper

@timer

def test(stop):

return next(filterfalse(lambda x: any(x%i for i in range(2, stop)), count(stop, stop)))

print("Test Function")

print(test(20))

# 11.526668787002563

# 232792560

这也让我想起了最近在Python中使用最大公分母函数为最小公倍数进行代码斗争时必须回答的一个问题。代码如下:import time

from fractions import gcd

from functools import reduce

def timer(func):

def wrapper(*args, **kwargs):

start = time.time()

res = func(*args, **kwargs)

print(time.time() - start)

return res

return wrapper

@timer

def leastCommonDenominator(denominators):

return reduce(lambda a, b: a * b // gcd(a, b), denominators)

print("LCM Function")

print(leastCommonDenominator(range(1, 21)))

# 0.001001596450805664

# 232792560

与大多数编程任务一样,有时最简单的方法并不总是最快的。不幸的是,这一次在Python中尝试时,它真的很突出。也就是说,Python的优点在于获得性能执行的简单性,它需要10行C,我能够(潜在地)在一行lambda表达式中返回正确的答案,比我在C上的简单优化快300倍。我不是C#的专家,但是在这里实现相同的方法是我使用的代码及其结果(大约比Python快5倍):using System;

using System.Diagnostics;

namespace ConsoleApp1

{

class Program

{

public static void Main(string[] args)

{

Stopwatch t0 = new Stopwatch();

int maxNumber = 20;

long start;

t0.Start();

start = Orig(maxNumber);

t0.Stop();

Console.WriteLine("Original | {0:d}, {1:d}", maxNumber, start);

// Original | 20, 232792560

Console.WriteLine("Original | time elapsed = {0}.", t0.Elapsed);

// Original | time elapsed = 00:00:02.0585575

t0.Restart();

start = Test(maxNumber);

t0.Stop();

Console.WriteLine("Test | {0:d}, {1:d}", maxNumber, start);

// Test | 20, 232792560

Console.WriteLine("Test | time elapsed = {0}.", t0.Elapsed);

// Test | time elapsed = 00:00:00.0002763

Console.ReadLine();

}

public static long Orig(int maxNumber)

{

bool found = false;

long start = 0;

while (!found)

{

start += maxNumber;

found = true;

for (int i=2; i < 21; i++)

{

if (start % i != 0)

found = false;

}

}

return start;

}

public static long Test(int maxNumber)

{

long result = 1;

for (long i = 2; i <= maxNumber; i++)

{

result = (result * i) / GCD(result, i);

}

return result;

}

public static long GCD(long a, long b)

{

while (b != 0)

{

long c = b;

b = a % b;

a = c;

}

return a;

}

}

}

然而,对于大多数更高级别的任务,我通常看到Python与.NET实现相比做得非常好,尽管我目前无法证实这些说法,除了说Python请求库在性能上给了我比用同样方式编写的C web请求高出两到三倍的回报之外。在编写Selenium进程时也是这样,因为我可以在100毫秒或更短的时间内读取Python中的文本元素,但是每个元素检索都需要C#&gt;1秒才能返回。也就是说,我实际上更喜欢C#实现,因为它采用面向对象的方法,Python的Selenium实现可以正常工作,有时很难阅读。