23
$\begingroup$

VectorQ and similar functions (MatrixQ, ArrayQ) treat certain second arguments specially.

For example, this is very fast:

rr = RandomReal[{0.01, 1}, 100000];

VectorQ[rr, NumericQ]; // RepeatedTiming
(* {5.*10^-7, Null} *)

While this is not:

VectorQ[rr, Positive]; // RepeatedTiming
(* {0.022, Null} *)

This is because when rr is a packed array, VectorQ will not evaluate NumericQ for each array element separately. Since all elements of a packed array are of the same type, it is clear what the answer should be without checking each of them.

Question: Which functions are treated specially by VectorQ?

Why is this important? Constructs like VectorQ[#, NumericQ]& are frequently used for argument checking. You'd want to know what patterns to use for optimal performance. Argument checking should ideally take negligible time compared to the actual computation the function does.

$\endgroup$

1 Answer 1

22
$\begingroup$

VectorQ is specially optimized with the following functions

The following were tested in M11.3 unless stated otherwise. Past versions may behave differently.

  • NumberQ, NumericQ (verified in M10.0)

  • MachineNumberQ

  • IntegerQ

  • Developer`MachineRealQ, Developer`MachineIntegerQ, Developer`MachineComplexQ (verified in M10.0 but see bug below)

  • Internal`PositiveIntegerQ, Internal`NegativeIntegerQ, Internal`NonNegativeIntegerQ, Internal`NonPositiveIntegerQ (M11.1+ only)

  • Internal`PositiveMachineIntegerQ, Internal`NegativeMachineIntegerQ, Internal`NonNegativeMachineIntegerQ, Internal`NonPositiveMachineIntegerQ (M11.1+ only)

  • Internal`RealValuedNumberQ, Internal`RealValuedNumericQ

Functions you might expect VectorQ to be optimized for, but it is not

Keep in mind that the following were tested in M11.3. Things may change in future versions.

  • Developer`RealQ
  • Positive, Negative, NonPositive, NonNegative (these are not ...Q functions but optimizing them for packed arrays would make sense)

Bugs to be aware of

In Mathematica 10.4 and earlier, the following return the incorrect False result:

VectorQ[{}, Developer`MachineIntegerQ]
VectorQ[{}, Developer`MachineRealQ]
VectorQ[{}, Developer`MachineComplexQ]
$\endgroup$
3
  • $\begingroup$ Is NumericQ as fast as Internal`RealValuedNumericQ? $\endgroup$
    – b3m2a1
    Commented Oct 23, 2018 at 17:41
  • $\begingroup$ @b3m2a1 I'm not sure, but thanks for pointing to that function! This post is not about the performance of these functions, but whether VectorQ recognizes them and avoids calling them entirely for better performance. $\endgroup$
    – Szabolcs
    Commented Oct 23, 2018 at 18:40
  • $\begingroup$ sorry that’s what I meant. I did the check and it also checks the packed-ness (it’s actually faster by some marginal fraction which might be its lack of generality). $\endgroup$
    – b3m2a1
    Commented Oct 23, 2018 at 20:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.