Evaluate Piecewise Functions Effciently

Dear all,

I have a very basic (maybe stupid) question. I need to evaluate a piecewise function many times. My naive approach is to do something like:

function myPiecewise(a,b)
  if a < 0
    return 0.5*a + b
  else 
   return - 2.5*a + b
  end
end

Is that an efficient way of implementing piecewise functions? I could just create two functions, one for the negative case and another for the positive case. Would that be better in terms of performance?

Thanks!

Check this older post on same topic.

2 Likes

Thanks. I saw that post before posting my question. As far as I understand, in their case, they can’t increase performance using the alternative to the naive solution. That’s why I posted my question.

I would think that your implementation is fast. After all, it is only a single branch and should only take a few nanoseconds to run. Unless this is a serious performance bottleneck (which I doubt) I wouldn’t care about optimising it (if possible).

FWIW:

julia> @btime myPiecewise($(Ref(1))[],$(Ref(2))[]);
  3.456 ns (0 allocations: 0 bytes)

Out of curiosity (and stupidity) I tested ifelse that avoids the branch. The timing is the same.

julia> nobranch(a,b) = ifelse(a<0,0.5*a+b,-2.5*a+b)
nobranch (generic function with 1 method)

julia> @code_llvm debuginfo=:none nobranch(1,2)

define double @julia_nobranch_685(i64, i64) {
top:
  %2 = icmp sgt i64 %0, -1
  %3 = sitofp i64 %0 to double
  %4 = sitofp i64 %1 to double
  %.p.v = select i1 %2, double -2.500000e+00, double 5.000000e-01
  %.p = fmul double %.p.v, %3
  %5 = fadd double %.p, %4
  ret double %5
}

julia> @btime nobranch($(Ref(1))[],$(Ref(2))[]);
  3.456 ns (0 allocations: 0 bytes)
5 Likes