2

The question pretty much says it all. At the moment, I'm using Math.Abs(a - b) to calculate the absolute value of a subtraction expression, example 5 - 10 and 10 - 5 both returning 5.

Is there a more efficient way to do this, or it is the most efficient way?

Hamid Pourjam
  • 20,441
  • 9
  • 58
  • 74
Shadow
  • 3,926
  • 5
  • 20
  • 41

1 Answers1

2

Please do not micro optimize your code until you know exactly where the problem is.

You can implement one your self and make it an inline function to reduce the cost of function call by using MethodImplAttribute.

If you are using Int32 Values and your inputs are not happen to be boundary values then you can use this

Abs(x) = (x ^ (x >> 31)) - (x >> 31)

but I suggest you to forget all about it, profile your application, you will see the real problem is somewhere else not in calling Math.Abs, You should always make your code readable first then tweak performance problems after you prove that they are really performance problems!

Programmers waste enormous amounts of time thinking about, or worrying about, the speed of noncritical parts of their programs, and these attempts at efficiency actually have a strong negative impact when debugging and maintenance are considered. We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3%.
(DonaldKnuth's paper "StructuredProgrammingWithGoToStatements")

read this please

Hamid Pourjam
  • 20,441
  • 9
  • 58
  • 74
  • 1
    Agreed. I'm a game developer and I've never needed to optimize out an absolute value calculation. (But if I were doing graphics programming, that would be a whole 'nother animal.) – piojo Dec 09 '14 at 07:53
  • 1
    And even in graphics, reordering the instructions and choosing the right mix of datatypes will be more benefit than a different way of doing abs. :) – Peter Dec 09 '14 at 08:39
  • Calculating that expression is prob. slower than `x>=0 ? x : -x`, which could compile to (input in edi / output in eax): `xor eax, eax / sub eax, edi / cmovle eax, edi` on x86. 2 instructions on the critical path, both with low latency. cmovLE = conditional copy if the previous compare was Less-than or Equal. (i.e. if `0 <= input`, `output=input`, else keep the `0-output` that also acted as the compare.) Hrm, clang uses my idea, gcc uses your xor/shift/sub. ICC uses `cltd` to copy the sign bit of the input to every bit of another register, instead of shift. https://goo.gl/Lj9JeR. – Peter Cordes Sep 09 '15 at 05:20