Delphi事始め

#Why Delphi?

私が.netと比較してDelphi/C++ builderを検討するのは下記の理由からです。

・VCLクラスライブラリがわかりやすい（.netの源流）
・リバースエンジニアリングが難しい
・Microsoftのサポートポリシーに振り回されない（.net6から3年おきとか。。泣）
・高速


個人的にはWindowsネイティブ開発の最適解かなと思っていますが、仕事はないですね。。
なので、現在はC＃＋難読化で妥協していますが、プロダクト開発向けには最適なんじゃないかと思っています。

#で、今回のネタは？

本当に高速なのかベンチマークをとってみました。
メルセンヌ素数の判定アルゴリズムです。

#Delphi

```Project1.dpr

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++

```test.cpp
#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
```test.cs
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++と同等の速度が出るのが良いです。
リバースエンジニアリング耐性もありますし。。

自由に言語が選べる案件があれば使ってみたいな。。



以上、ベンチマーク報告でした。

#参考
https://qiita.com/asksaito/items/76b71602dd956b79dbf7