#Why Delphi?
私が.netと比較してDelphi/C++ builderを検討するのは下記の理由からです。
・VCLクラスライブラリがわかりやすい(.netの源流)
・リバースエンジニアリングが難しい
・Microsoftのサポートポリシーに振り回されない(.net6から3年おきとか。。泣)
・高速
個人的にはWindowsネイティブ開発の最適解かなと思っていますが、仕事はないですね。。
なので、現在はC#+難読化で妥協していますが、プロダクト開発向けには最適なんじゃないかと思っています。
#で、今回のネタは?
本当に高速なのかベンチマークをとってみました。
メルセンヌ素数の判定アルゴリズムです。
#Delphi
program Project1;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils,Math,Diagnostics;
function IsPrime(num: Int64) : Boolean;
var
sqrtNum : Int64;
i : Int64;
begin
if num < 2 then Result := False
else if (num = 2) then Result := True
else if (num mod 2 = 0) then Result := False; // 偶数はあらかじめ除く
sqrtNum := Floor(Sqrt(num));
i:=3;
while i <= sqrtNum do
begin
if num mod i = 0 then
begin
// 素数ではない
Result := False;
end;
i := i + 2;
end;
// 素数である
Result := True;
end;
begin
var
AStopWatch : TStopwatch;
AStopWatch := TStopwatch.StartNew;
Writeln(IsPrime(2305843009213693951));
AStopWatch.Stop;
Writeln(AStopWatch.ElapsedMilliseconds);
end.
##VC++
#include <iostream>
#include <math.h>
#include <chrono>
bool IsPrime(long long num)
{
if (num < 2) return false;
else if (num == 2) return true;
else if (num % 2 == 0) return false; // 偶数はあらかじめ除く
double sqrtNum = sqrt(num);
for (long long i = 3; i <= sqrtNum; i += 2)
{
if (num % i == 0)
{
// 素数ではない
return false;
}
}
// 素数である
return true;
}
int main()
{ // 開始・終了時間を各々で記録する変数
std::chrono::system_clock::time_point begin;
std::chrono::system_clock::time_point end;
// この区間の開始・終了時刻を取る
begin = std::chrono::system_clock::now();
std::cout << IsPrime(2305843009213693951) << std::endl;
end = std::chrono::system_clock::now();
// ミリ秒をdouble型で取得する
std::cout << "Elapsed(msec) = "
<< std::chrono::duration_cast<std::chrono::milliseconds>(end - begin).count() << std::endl;
}
##C Sharp
using System;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
var sw = new System.Diagnostics.Stopwatch();
//-----------------
// 計測開始
sw.Start();
Console.WriteLine(IsPrime(2305843009213693951));
// 計測停止
sw.Stop();
// 結果表示
Console.WriteLine($" {sw.ElapsedMilliseconds}ミリ秒");
}
public static bool IsPrime(Int64 num)
{
if (num < 2) return false;
else if (num == 2) return true;
else if (num % 2 == 0) return false; // 偶数はあらかじめ除く
double sqrtNum = Math.Sqrt(num);
for (int i = 3; i <= sqrtNum; i += 2)
{
if (num % i == 0)
{
// 素数ではない
return false;
}
}
// 素数である
return true;
}
}
}
#結果
Delphi x64 Release
5842 msec
VC++ x64 Release
5992 msec
C# x64 Release
5999 msec
全般的にDelphiが早い結果になりました。
書き方によって早い、遅いは変わってくるとは思いますが、書き方を工夫すれば、c++と同等の速度が出るのが良いです。
リバースエンジニアリング耐性もありますし。。
自由に言語が選べる案件があれば使ってみたいな。。
以上、ベンチマーク報告でした。