C#学習日記 – 素数判定とPythonの速度比較、そして言語間の相互理解性
一年前、初めてPythonで素数判定を書きました(『Python学習日記 – 素数判定』)。先日、『C# 図解教程』という新しい本を手に入れ、友人たちとプログラミング言語の効率について話し合ったこともあり、C#で素数判定を書いてPythonのものと比較してみようと思いました。Pythonで書いた素数判定アルゴリズムは非常に非効率で、8桁を超える数の素数計算は非常に遅くなります。C#ではどうなるのか、まだ分かっていません。
比較するために、C#ではPythonと同じ計算方法を使用しました。以下の動画で対比しています。
Pythonのコードは、私の『Python学習日記 – 素数判定』の書き方と少し異なります。timeモジュールを導入してプログラムの実行時間を計測しているためです。一方、C#ではSystem.Diagnosticsを使用して計測しています。どちらも言語の組み込みモジュールであり、プログラムの実行には大きな影響を与えません。
動画を見ると明らかなように、同じアルゴリズムを使用した場合、C#の実行速度はPythonの数倍です。しかし、その代償として、C#のコードはPythonよりもかなり複雑になります。
コードから計測部分と冗長な部分を取り除いてみましょう。
Console.Write("请输入一个整数:");
int InputNumber = Convert.ToInt32(Console.ReadLine());
int ConutNumber = 0;
for (int i = 1; i < InputNumber; i++)
{
if (InputNumber % i == 0)
{
ConutNumber = ConutNumber + 1;
}
}
if (ConutNumber >= 2)
{
Console.WriteLine($"{InputNumber} 不是素数");
}
else
{
Console.WriteLine($"{InputNumber} 是素数");
}
python
x = int(input('输入一个数:'))
z = 0
for i in range(1,x+1):
if x % i == 0:
z = z+1
if z >= 2:
print(f"{x} 不是素数")
else:
print(f"{x} 是素数")
この2つのコードのうち、最初のものはC#で書かれており、2番目のものはPythonで書かれています。使用しているアルゴリズムはどちらも、その数を1からその数までのすべての数で割り、いくつの数で割り切れるかを調べるというものです。割り切れる数が2より多ければ、それは素数ではないと判定されます。
同じアルゴリズムを使用した場合、C#の速度はPythonの数倍を上回ります。高性能の背後には構文の複雑さがありますが、比較してみると、この2つの異なる言語には驚くべき共通点があることが分かります。もしあなたがPythonの構文だけを学んでいて、今になってC#を見返すと、C#でも同じようにメソッドで入力を受け取り、同じようにif-else文で計算結果を判定し、同じような比較演算子や剰余演算子を使用していることに気づくでしょう。
これこそが、プログラミング初心者に、より簡単な言語を学んでコードの世界に入ることを勧める理由です。
もちろん、このアルゴリズムをより高速にするためには、もっと賢い方法があります。Pythonは簡単なので、Pythonの書き方を例に、素数計算の改善方法を説明します。
上記のアルゴリズムでは、1 から x+1 までのすべての数で入力された数を割る必要があるため、非常に大きな数の場合、すでに複数の数で割り切れてzの値が2より大きくなっているにもかかわらず、for ループが中断されないという問題が発生します。解決策は簡単で、forループ内にzの値の判定を追加すればよいのです。
if z >= 2:
break;
for ループ内でこの数が2以上になった場合、for ループが中断され、その時点で z の値は2より大きくなっているため、素数ではないと正しく判定できます。もちろん、同じ方法でミリ秒単位まで比較すれば、やはりC#の方が優れています。