今日の初めに、私はパフォーマンスに関心があったので、Mathematica で述語関数に一致する要素をカウントする慣用的な方法があるかどうかを尋ねました。
特定の述語に対する私の最初のアプローチpred
は次のとおりです。
PredCount1[lst_, pred_] := Length@Select[lst, pred];
代わりに使用する提案を得ました
PredCount2[lst_, pred_] := Count[lst, x_/;pred@x];
これらの関数のプロファイリングをさまざまなlst
サイズとpred
関数で開始し、さらに 2 つの定義を追加しました。
PredCount3[lst_, pred_] := Count[Thread@pred@lst, True];
PredCount4[lst_, pred_] := Total[If[pred@#, 1, 0] & /@ lst];
データ サンプルは 100 万から 1000 万要素の範囲で、テスト関数はとEvenQ
でした。次のグラフは、所要時間を示しています。#<5&
PrimeQ
イーブンQ
PredCount2 が最も遅く、3 と 4 で十分です。
比較述語: #<5&
実際の問題で必要なものに近いため、この関数を選択しました。これがばかげたテスト関数であることを心配しないでください。実際には、4 番目の関数に何らかのメリットがあることが証明されており、実際にソリューションで使用することになりました。
と同じEvenQ
ですが、3 は 4 より明らかに遅いです。
プライムQ
これは奇妙です。すべてがひっくり返る。最悪の値は最後に計算された関数に対するものであるため、ここでの原因としてキャッシングを疑っていません。
では、特定の述語関数に一致するリスト内の要素の数を数える正しい (最速の) 方法は何ですか?