wolfram-mathematica - 计算与谓词匹配的元素的最快方法

标签 wolfram-mathematica

今天早些时候我问是否有 idiomatic way to count elements matching predicate Mathematica 中的函数,因为我关心性能。

我对给定谓词的初始方法 pred如下:

PredCount1[lst_, pred_] := Length@Select[lst, pred];

我收到了改用的建议

PredCount2[lst_, pred_] := Count[lst, x_/;pred@x];

我开始分析这些函数,使用不同的 lst尺寸和pred函数,并添加了两个定义:

PredCount3[lst_, pred_] := Count[Thread@pred@lst, True];
PredCount4[lst_, pred_] := Total[If[pred@#, 1, 0] & /@ lst];

我的数据样本范围在 1 到 1000 万个元素之间,我的测试函数是 EvenQ , #<5&PrimeQ 。下图显示了所花费的时间。

EvenQ EvenQ predicate

PredCount2 最慢,3 和 4 不相上下。

比较谓词:#<5&

我选择了这个函数,因为它接近我实际问题所需的功能。不要担心这是一个愚蠢的测试函数,它实际上证明了第四个函数有一些优点,我实际上最终在我的解决方案中使用了它。

Less than five predicate

EvenQ 相同,但 3 明显比 4 慢。

PrimeQ PrimeQ predicate

这太奇怪了。一切都翻转了。我并不怀疑缓存是罪魁祸首,因为最差的值是最后计算的函数的值。

那么,计算列表中与给定谓词函数匹配的元素数量的正确(最快)方法是什么?

最佳答案

您正在看到自动编译的结果。

首先,对于 Listable 函数(例如 EvenQPrimeQ),不需要使用 Thread:

EvenQ[{1, 2, 3}]
{False, True, False}

这也解释了为什么 PredCount3 在这些函数上表现良好。 (它们针对列表上的线程进行了内部优化。)

现在让我们看看时间安排。

dat = RandomInteger[1*^6, 1*^6];

test = # < 5 &;

First@Timing[#[dat, test]] & /@ {PredCount1, PredCount2, PredCount3, PredCount4}
{0.343, 0.437, 0.25, 0.047}

如果我们更改系统选项以防止 Map 内自动编译并再次运行测试:

SetSystemOptions["CompileOptions" -> {"MapCompileLength" -> Infinity}]

First@Timing[#[dat, test]] & /@ {PredCount1, PredCount2, PredCount3, PredCount4}
{0.343, 0.452, 0.234, 0.765}

您可以清楚地看到,如果不编译,PredCount4 会慢得多。简而言之,如果您的测试函数可以由 Mathematica 编译,那么这是一个不错的选择。

Here are some other examples of fast counting using numeric functions.

关于wolfram-mathematica - 计算与谓词匹配的元素的最快方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10350177/

相关文章:

math - 如何制作有理数的 "working"重复十进制表示?

scripting - mathematica 从命令行启动前端和评估笔记本

wolfram-mathematica - 数学中的消息生成

wolfram-mathematica - Mathematica 中没有垂直线的直方图

3d - 在 Mathematica 7 中使用抗锯齿进行慢速 3D 旋转

wolfram-mathematica - 如何加快 Mathematica 替换矩阵元素

wolfram-mathematica - 数学 : Text in Graphics3D relative to image coordinates

wolfram-mathematica - 如何使用条件即时构建列表,功能方式

wolfram-mathematica - 在 Mathematica 中精确绘制两条折线时,PlotMarkers 会消失吗?

wolfram-mathematica - 在 Workbench 中比较笔记本的步骤