![見出し画像](https://assets.st-note.com/production/uploads/images/143993469/rectangle_large_type_2_30ee391c859e725a2a24cff70d22cff4.jpeg?width=1200)
【DataWeave】ループ処理の入れ子を避けて効率的・性能がいいコードを書く方法
はじめに
こんにちは。CREFILでコンサルタントをしている片野です。
今回は、ループ処理の入れ子による性能の低下の回避方法をお伝えします。
ループ処理を複数回使用して処理時間がかかってしまったり、メモリを使いすぎてしまったことはないでしょうか?
最近そんな場面があったので、その時に学んだループ処理の回避について共有しようと思います!
また、今回のブログではDataWeaveというMuleSoftのAnypoint Platformの一部として提供されるデータ変換言語を使用します。
ループの入れ子処理とは
ループ処理の入れ子とは、プログラム内で1つのループが別のループの中に配置されるプログラムの制御構造を指します。
具体的に記載してみると以下のようになります。
(処理の目的は「社員情報に該当社員のプロジェクト情報を合体させる」です。)
%dw 2.0
output application/json
---
// 入れ子になっているプログラミング
employees map (value) ->
value
++
{
"projects": (projects filter ($.no == value.no)).projects[0]
}
プログラムの処理内容は、
社員情報を持っている配列の変数[employees]にprojectsという項目を追加し、projectsの値はプロジェクト情報を持っている配列の変数[projects]から二つの変数の項目「no」が一致するものを探しています。
上記の処理を行うためにループ処理(map)の中でループ処理(filter)を行い、外側のループ処理が実行されるたびに内側のループ処理が毎回実行されます。
単純に100万人の社員情報があるとすると、100万(社員情報)×100万(プロジェクト情報)回処理が行われてしまう、というわけです。
少ないデータ量であればさほど問題はありませんが、特に大規模なデータセットを処理する際にパフォーマンスの低下やコードの複雑さを引き起こす可能性があります。
補足
上記の処理をinputデータありで確認されたい方は、「PlayGround」で、以下のzipファイルをImportしていただければ、より動きがわかりやすいかなと思うので、よければぜひ確認してみてください!
PlayGround使用方法の参考ブログ:https://note.com/crefil/n/n83dcc8329972
入れ子処理を避ける対応策
入れ子処理を避ける手段として「groupBy」を紹介します!
groupByとは、指定された条件によって配列の項目をグループ化してオブジェクトを返します。
groupByによって作成された変数はDBでいうところのINDEXがはられた状態になるので、変数内で該当データを探す際の処理が早くなります!
具体的に記載してみると以下のようになります。
(処理の目的は上記と同様で「社員情報に該当社員のプロジェクト情報を合体させる」です。)
%dw 2.0
output application/json
var prGroupBy = projects groupBy (item) -> item.no
---
// 入れ子を避けているプログラム
employees map (value) ->
value
++
{
"projects": prGroupBy[value.no].projects[0]
}
今回使用しているgroupByでは、配列の変数を、項目の値ごとにグループ化しています。
プログラムの処理内容は
項目「no」でグループ化された変数[prGroupBy]を作成し、変数[employees]のループ処理中に該当するデータを変数[prGroupBy]から検索しています。
入れ子処理の時とは違い、ループ内の処理ごとに変数[projects]をすべて確認しなくなります。
この処理でしたら、社員情報が100万件、プロジェクト情報が100万件あっても処理回数は100万回になります。
補足
groupByを使用した処理も「PlayGround」で確認できるようにzipファイルを添付しますので、よければ確認してみてください!
さいごに
今回、ループの入れ子処理の回避方法を紹介しました。
よければ参考にしていただけたら嬉しいです。
最後まで読んでいただき、ありがとうございました。
よければ、「♡」していただければ幸いです!