A drawback of the Which command is that it evaluates x repeatedly until one of the conditions of Which is satisfied. This is time consuming when x is a complicated expression or/and when the set of conditions is large.
This is not true in Compile
as x
will always be a number or an array. Multiple uses of x
won't slow anything down.
It isn't even true outside of Compile
in most practical cases unless you defined x
using :=
instead of =
.
The command "Switch" only evaluates x once, but seems to be not compilable.
Simple forms of Switch
are compilable. In your question, you are misusing Switch
. It takes patterns, not true/false conditions. Please read the documentation.
When using it in Compile
, only literal patterns seem to be accepted. An exception is the last pattern, which must be _
to handle the default case.
Example:
cf = Compile[{{x, _Integer}},
Switch[x,
1, 10,
2, 20,
_, 0
]
]
"
1 argument
2 Boolean registers
8 Integer registers
Underflow checking off
Overflow checking off
Integer overflow checking on
RuntimeAttributes -> {}
I0 = A1
I1 = 1
I4 = 20
I2 = 10
I3 = 2
I5 = 0
Result = I7
1 B0 = I0 == I1
2 if[ !B0] goto 5
3 I7 = I2
4 goto 11
5 B1 = I0 == I3
6 if[ !B1] goto 9
7 I6 = I4
8 goto 10
9 I6 = I5
10 I7 = I6
11 Return
"
If you try to use a more general pattern, such as _Integer
or x_ /; x > 0
, it will trigger a call to MainEvaluate (i.e. it won't be compiled) for that particular test.
Warning: When testing with literal patterns, it is important to be aware that 1.
and 1
are considered to be different. We needed to explicitly specify that the input is an integer, otherwise it would be converted to a real (floating point) number, which never matches the integer 1
. Thanks to @MichaelE2 for pointing this out!
In summary:
Inside Compile
,
Apply
will be compiled only if its first argument isTimes
orPlus
. $\endgroup$Switch
in Mathematica, please check the document ofSwitch
carefully. $\endgroup$