やったこと・背景
以前の投稿で、if文を使ってループを回す方法と、C#のRange()
のようなアクションを自作し、それを使ってForEachでループを回す方法の2種類を試してみました。
しかし、自作したRangeアクションだとループを2つまわすことになり、性能に問題があるような気がしたので、それぞれの方法(+α)の処理時間を計測しました。
ついでにForEachの時間も計りました。
また、ExtensionでFor文を実行するのと、ServiceStudioで作ったアクションでループを回すのとで、処理時間にどれほど差が出るのか気になったので試してみました。
処理時間は、Forgeで提供されているTicksというComponentを使って計測しました。
環境
- Outsystems11 (Personal Environment)
- Traditional Web
計測方法・計測結果
100万回ループを回しました。
10回ずつ計測を行い、平均値を結果としています。
また、それぞれループの回数分1を足すという処理を行っています。
if文でループを回す
計測結果:1.600秒(100万回)
Rangeアクションを使ってループを回す
RangeアクションをServiceStudioで作った場合と、Extensionで作った場合で実行速度が結構違いました。
RangeアクションをServiceStudioで作った場合
計測結果:3.924秒(100万回)
RangeアクションをExtensionで作った場合
Rangeアクションは以下のように実装しました。
OutputParameterは、Integer型の項目のみを持つStructureのリストです。
publicvoidMssRange(intssStart,intssLength,outRLIntegerRecordListssIntegerList){ssIntegerList=newRLIntegerRecordList();// TODO: Write implementation for actionvartmpRecord=newRCIntegerRecord();for(inti=1;i<=ssLength;i++){tmpRecord.ssSTInteger.ssInteger=ssStart;ssIntegerList.Add(tmpRecord);ssStart+=1;}}// MssRange
計測結果:2.792秒(100万回)
ForEachだけの実行時間
Rangeアクションを実行した後~ForEachが終わるまでの時間も計ってみました。
計測結果:1.515秒
Extensionの中でfor文を実行
100万回だと値が小さすぎてうまく計測できなかったので、このパターンだけ10憶回ループを回しました。(ちなみにこれ以外のループでは、10憶回回すと余裕でタイムアウトしてしまいます。)
publicvoidMssForExtension(intssLength,outintssSum){// TODO: Write implementation for actionssSum=0;for(inti=0;i<ssLength;i++){ssSum+=1;};}// MssForExtension
計測結果:2.230秒(10憶回)
やりたかったこと
最初、C#のRange()
をラッピングしたExtensionを作れば今回自作したRangeアクションよりも早そうだと思ったのですが、ExtensionのOutputParameterに純粋なInt型のリストを設定できないので(やり方を知らないだけかも)結局、Range()
で生成したシーケンスをRecordListの型にキャストしなきゃいけないということがわかりました。が、(For文を使わずに)RecordListの型にキャストするのは難しそうだったので断念しました…。
まとめ
if文 | Range (ServiceStudio) | Range (Extension) | ForEach | Extension |
---|---|---|---|---|
1.600秒(100万回) | 3.924秒(100万回) | 2.792秒(100万回) | 1.515秒(100万回) | 2.230秒(10憶回) |
100万回のループで1秒以上かかるのはちょっと遅いなあと思いました。C#だけで実装した場合と全然速さが違いますね。