RAD Studio 12.2では、多くの新機能の追加や多数の機能強化が行われています。そのうちDelphi ランタイム ライブラリ (RTL) の分野にも注目すべき機能強化がいくつか行われております。
新しいTParallelArray クラス
System.Threadingユニットには、配列項目に対して &ForやSortなどの処理を並列実行できる新しいTParallelArrayクラスが追加されました。マルチコアシステムでは、これにより処理速度が大幅に向上します。
では、この新しいクラスをどのように使用するのでしょうか?
本ブログでは、2つの同一の配列を作成し、通常のシングルスレッドのSortと新しい並列バージョンでソートするコマンドラインプロジェクトを例に簡単なテストケースをご紹介いたします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
program ParallelArray; {$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils, System.Classes, System.Generics.Collections, System.Threading, System.Diagnostics; var A1, A2: array of Integer; I: Integer; T: TStopwatch; begin try SetLength(A1, 100_000_000); SetLength(A2, 100_000_000); for I := 0 to High(A1) do begin A1[I] := Random(MaxInt); A2[I] := A1[I]; end; // Warm up thread pool TTask.Create( procedure begin // empty end).Start; // Serial sorting T := TStopwatch.StartNew; TArray.Sort<Integer>(A1); T.Stop; Writeln('TArray.Sort: ', T.Elapsed.ToString); // Parallel sorting T := TStopwatch.StartNew; TParallelArray.Sort<Integer>(A2); T.Stop; Writeln('TParallelArray.Sort: ', T.Elapsed.ToString); except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; Readln; end. |
今回テストケースの検証のために使用したCPUのスペックは、(Intel(R) Core(TM) i7-10700 CPU @ 2.90GHz) で、このPC環境で実行したところ、585%の改善という素晴らしい結果が得られました。(読みやすくするために出力はミリ秒単位に切り詰められています)
1 2 |
TArray.Sort: 00:00:16.414 TParallelArray.Sort: 00:00:02.889 |
新しいTOrderedDictionary クラス
System.Generics.Collectionsユニットには、TDictionary<K,V>から派生した新しいTOrderedDictionaryクラスが追加されました。このOrdered Dictionaryという順番付きディクショナリは、ディクショナリ内にソート メソッドが統合されたディクショナリクラスです。このクラスを使用することによって、ソートされた順序でデータをナビゲートするfor inループを簡単に作成でき、要素の検索も高速化されます。
例として、以下の手順で実行するプロジェクトをご覧ください。
- 順番付きディクショナリを作成し、いくつかの要素を追加する
- 出力と、1億回キーを検索するのにかかった時間を表示する
- キーでソートし、再度出力を表示し、1億回の検索呼び出しを繰り返す (はるかに高速です!)
- 値でソートし、再度表示する
- 要素を追加する。並べ替え順序で要素が追加されていないことを証明するには、必要に応じて並べ替える必要があります (複数の要素を挿入する場合は、通常、この方が高速です)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
program OrderedDictionaryDemo; {$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils, System.Generics.Collections, System.Diagnostics; var T: TStopwatch; begin try var ODict := TOrderedDictionary <string, string>.Create; ODict.Add ('one', 'London'); ODict.Add ('two', 'Berlin'); ODict.Add ('three', 'Rome'); ODict.Add ('four', 'Athens'); ODict.Add ('five', 'Madrid'); ODict.Add ('six', 'Bruxelles'); ODict.Add ('seven', 'Paris'); writeln ('Natural'); for var APair in ODict do writeln (APair.Key + ' - ' + APair.Value); T := TStopwatch.StartNew; for var I := 0 to 100_000_000 do ODict.IndexOf('five'); T.Stop; Writeln('IndexOf unsorted: ', T.Elapsed.ToString); writeln; writeln ('SortByKeys'); ODict.SortByKeys; for var APair in ODict do writeln (APair.Key + ' - ' + APair.Value); T := TStopwatch.StartNew; for var I := 0 to 100_000_000 do ODict.IndexOf('five'); T.Stop; Writeln('IndexOf sorted: ', T.Elapsed.ToString); writeln; writeln ('SortByValues'); ODict.SortByValues; for var APair in ODict do writeln (APair.Key + ' - ' + APair.Value); writeln; writeln ('SortByValues plus extra item'); ODict.Add ('eight', 'Prague'); for var APair in ODict do writeln (APair.Key + ' - ' + APair.Value); writeln; readln; except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; end. |
出力結果は、以下の通りです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
Natural one - London two - Berlin three - Rome four - Athens five - Madrid six - Bruxelles seven - Paris IndexOf unsorted: 00:00:01.2720716 SortByKeys five - Madrid four - Athens one - London seven - Paris six - Bruxelles three - Rome two - Berlin IndexOf sorted: 00:00:00.6366114 SortByValues four - Athens two - Berlin six - Bruxelles one - London five - Madrid seven - Paris three - Rome SortByValues plus extra item four - Athens two - Berlin six - Bruxelles one - London five - Madrid seven - Paris three - Rome eight - Prague |
RTLのさらなる機能強化
- TRegistryクラスは、rdMultiStringのサポートが改善され、新しいメソッド ReadNoneおよびWriteNone(Windowsのレジストリ値の型であるREG_NONEにマップ)が追加されました。
- System.DateUtilsのRFC822形式の日付のサポートが改善されました。
- RAD Studioに同梱されているDelphiランタイムパッケージ向けのマップファイルが提供されるようになりました。
今回のブログは以上となります。RAD Studio 12.2で追加された多くの新しいRTL機能を、ぜひプロジェクトで活用してください。
Design. Code. Compile. Deploy.
Start Free Trial Upgrade Today
Free Delphi Community Edition Free C++Builder Community Edition