且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Mathematica 的模式匹配优化不佳?

更新时间:2023-11-23 19:04:28

MatchQ 为这些类型的测试解包.原因是没有为此实施任何特殊情况.原则上它可以包含任何东西.

MatchQ unpacks for these kinds of tests. The reason is that no special case for this has been implemented. In principle it could contain anything.

On["Packing"]
MatchQ[list, {x_Integer, y__}] // Timing

MatchQ[list, {x__Integer, y__}] // Timing

改进这一点非常棘手 - 如果您破坏了模式匹配器,您就会遇到严重的问题.

Improving this is very tricky - if you break the pattern matcher you have a serious problem.

编辑 1:确实,拆包不是 O(n^2) 复杂度的原因.但是,它确实表明对于 MatchQ[list, {x__Integer, y__}] 部分,代码转到算法的另一部分(需要解包列表).其他一些需要注意的事情:只有当两种模式都是 __ 时才会出现这种复杂性,如果其中之一是 _ 算法具有更好的复杂性.

Edit 1: It is true that the unpacking is not the cause for the O(n^2) complexity. It does, however, show that for the MatchQ[list, {x__Integer, y__}] part the code goes to another part of the algorithm (which needs the lists to be unpacked). Some other things to note: This complexity arises only if both patterns are __ if either one of them is _ the algorithm has a better complexity.

该算法然后遍历所有 n*n 个潜在匹配项,并且似乎没有提前救助.大概是因为可以构建需要这种复杂性的其他模式 - 问题是上述模式迫使匹配器采用非常通用的算法.

The algorithm then goes through all n*n potential matches and there seems no early bailout. Presumably because other patters could be constructed that would need this complexity - The issue is that the above pattern forces the matcher to a very general algorithm.

然后我希望 MatchQ[list, {Shortest[x__Integer], __}] 和朋友,但无济于事.

I then was hoping for MatchQ[list, {Shortest[x__Integer], __}] and friends but to no avail.

所以,我的两分钱:要么使用不同的模式(并使用 On["Packing"] 来查看它是否进入通用匹配器)或进行预检查 DeveloperPackedArrayQ[expr] &&Head[expr[[1]]]===Integer 之类的.

So, my two cents: either use a different pattern (and have On["Packing"] to see if it goes to the general matcher) or do a pre-check DeveloperPackedArrayQ[expr] && Head[expr[[1]]]===Integer or some such.