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#>;1秒才能傳回。也就是說,我實際上更喜歡C#實作,因為它采用面向對象的方法,Python的Selenium實作可以正常工作,有時很難閱讀。