MatchQ
распаковывает для этих видов испытаний.Причина в том, что особого случая для этого не было реализовано.В принципе, может содержать что-либо.
On["Packing"]
MatchQ[list, {x_Integer, y__}] // Timing
MatchQ[list, {x__Integer, y__}] // Timing
Улучшить это очень сложно - если вы нарушите механизм сопоставления с образцом, у вас возникнет серьезная проблема.
Редактировать1: Это правда, что распаковка не является причиной сложности O (n ^ 2).Это, однако, показывает, что для части MatchQ[list, {x__Integer, y__}]
код переходит к другой части алгоритма (которая требует распаковки списков).Некоторые другие вещи, на которые следует обратить внимание: эта сложность возникает, только если оба шаблона равны __
, если один из них равен _
, алгоритм имеет лучшую сложность.
Затем алгоритм проходит через все n * n потенциальных совпаденийи, похоже, ранней помощи нет.Предположительно, потому что могут быть построены другие шаблоны, которые будут нуждаться в этой сложности. Проблема в том, что приведенный выше шаблон вынуждает сопоставителя к очень общему алгоритму.
Я тогда надеялся на MatchQ[list, {Shortest[x__Integer], __}]
и друзей, но безрезультатно.
Итак, мои два цента: либо используйте другой шаблон (и включите On ["Packing"], чтобы увидеть, подходит ли он к общему совпадению), либо сделайте предварительную проверку DeveloperPackedArrayQ[expr] && Head[expr[[1]]]===Integer
или какую-то другую.