0

Is it possible to re-write the following so that it doesn't contain any conditional statements? I'm thinking there might be some clever trick using something like bitwise operations?

int a = // some value
int b = // some other value between 0 and max int
if(b >= 3)
{
    return a + 1;
}
else
{
    return a;
}

EDIT: to be clear, I'm not looking for a generic way of removing conditionals. I'm looking for a trick to remove the conditionals from this very specific code. Think of it as an academic puzzle.

To give an example, one way to remove conditionals (which happens to yield perf gains in some situations) is to precompute a lookup table and index into that with b instead. In this particular case this is tricky because b could be a very large number. Is there another way?

Ben
  • 1,321
  • 15
  • 30
  • Why replace a clear and understable code with some more obscure bitwise operation? Stay with the if's, code readability is important. and if you are thinking about performance... think if you really need to save a few clock cycle: you won't notice any difference in a million of iteration, I think – Gian Paolo Nov 05 '15 at 21:03
  • 1
    Of course you can. It is very easy: `return b>>x==y?z< – Racil Hilan Nov 05 '15 at 21:04
  • Is it not okay to ask a question like "is this possible"? Or put another way, is it necessary to know why I would want to do this in order to answer whether it is possible or not? – Ben Nov 05 '15 at 21:06
  • @GianPaolo it is for performance reasons in fact, and it can *totally* make a difference when you have a lot of iterations. – Ben Nov 05 '15 at 21:10
  • Ok. let me tell you something. You want to count from `1` to `1000000000000`. what is the fastest way to count this? `i++` ? nope. the answer is dont do it at all. if you want to make your program run faster you must look for other parts or probably look for better way to achieve what you want. – M.kazem Akhgary Nov 05 '15 at 21:12
  • @RacilHilan any chance you can un-pick that line of code a bit for me? Maybe as an answer rather than a comment? – Ben Nov 05 '15 at 21:12
  • @M.kazemAkhgary Sorry, I don't follow your argument. (And I can hardly prevent you from telling me something.) – Ben Nov 05 '15 at 21:16
  • 2
    @Ben Pretty sure what Racil posted was a joke, its not valid code. The point though, and most may agree, is that you are picking the wrong performance optimizations, branches are very fast. – Ron Beyer Nov 05 '15 at 21:17
  • @RonBeyer Hmm, maybe yeah. Although they *do* keep adding strange new operators to C#... – Ben Nov 05 '15 at 21:18
  • I think, @M.kazem Akhgary, that you shouldn't assume to know the situation in which I am using said code (it is a very large tight loop in a Unity game running on the equivalent of .NET 2 via Mono). Context matters. – Ben Nov 05 '15 at 21:24
  • @Ben your code is fastest. what you want is like to calculate `1 + 1 = 2` without adding `1+1`. It is not possible and `1+1` needs to be done. actually the condition is just a byte. but bitwise operations need 4 bytes to be calculated inside ALU. also ternary is shorter but seems slower. take a look at here http://stackoverflow.com/questions/17328641/ternary-operator-is-twice-as-slow-as-an-if-else-block – M.kazem Akhgary Nov 05 '15 at 21:28
  • 1
    Ben, Like Ron said, it's a joke. But the real point is this: are you asking for the shortest code, or the fastest code? Because when you say **Although they do keep adding strange new operators to C#**, then you're mostly talking about shorter not faster. Yes, I fully agree with you that the context matter, but you forgot to mention the very important "context" in your question. You should've said **is there any faster code...**, and the answer is **NO. The code that you posted is the fastest possible way of doing it**. Any other code will be slower, guaranteed. – Racil Hilan Nov 05 '15 at 21:30
  • @RacilHilan Yes, you're right it must be a joke (hence my "Although they do... " line - also a joke). I think you misinterpreted my use of "context matters": the context I was referring to was where this code is, what platform I am running on, what JIT compiler is being used, etc. None of this context was in question because it is irrelevant. My question was purely of the form "can this be done?". The fact that it is to do with performance isn't relevant - for any posted answers it would be a no-brainer to check perf on my local system anyway. – Ben Nov 05 '15 at 22:00
  • 1
    Yes, I understood your context properly and I agree with it. However, the performance is very relevant and actually required, because without it your question "can it be done" is meaningless. Of course it can be done. Everything can be done in different ways, but the real question is "can it be done in a better way", and now "better" needs a context "better in what way". This is reflected in your comment to Roka's answer "that is only better in one sense". So the bottom line is "Can it be done in different ways?", of course it can. "Can it be done faster?" no it can't. – Racil Hilan Nov 06 '15 at 02:17
  • Understood, but to be clear, I never asked for a 'better' way. And I've yet to see one a different way that doesn't use branching. I believe it can probably be done and if I it can then I'm pretty sure I can get a perf benefit *in my context*. Perhaps I'm wrong but I want a chance try so I really did't want to get bogged down in an up-front perf discussion. – Ben Nov 06 '15 at 07:18

4 Answers4

4

Here you go

return a - ((2 - b) >> 31);

Explanation:

r = 2 - b, < 0 (i.e. high bit set) for b >= 3

r >> 31, = -1 for b >= 3, 0 otherwise

Ivan Stoev
  • 195,425
  • 15
  • 312
  • 343
2
uint a = // some value
uint b = // some other value between 0 and max int
bool c = b & 0xFFFC
return a + Convert.ToInt32(c);

The fastest will probably be as bitwise operations tend to be very fast

uint a = // some value
uint b = // some other value between 0 and max int
return (b & 0xFFFC) ? a+1 : a;
Dave S
  • 3,378
  • 1
  • 20
  • 34
0

You could make it better by doing this:

int a = // some value
int b = // some other value between 0 and max int
return (b >= 3) ? (a+1) : a;
Roka
  • 444
  • 5
  • 23
  • 1
    Better in that it is fewer lines of code, but that is only 'better' in one sense (and not necessarily a reasonable one). – Ben Nov 05 '15 at 21:09
0

?: operator. (but yet it contains conditional statement.)

return b >= 3 ? a + 1 : a;

or

return a + (b >= 3 ? 1 : 0);

Is it possible to re-write the following so that it doesn't contain any conditional statements?

It is not possible to make it work out of no where. you must check this condition any way. There is no magic.

If you want to make your program faster by removing this condition then you picked wrong way. this is micro optimization.

M.kazem Akhgary
  • 18,645
  • 8
  • 57
  • 118