开发者

Is ternary operation better than "if/else" in iPhone

I have this block in my program:

if (x > 0) {
    a = 1;
    b = 4;
} else {
    a = 2;
    b = 3;
}

This can be written with ternary operation like this:

a = (x > 0) ? 1 : 2;
b = (x > 0) ? 4 : 3;

The results are equivalents, but it's part of a really critical part of my application, running thousands of times per second. I want to sq开发者_如何学Goueeze some microseconds, because this method will grow a little.

My question: in ARM level, which one is faster? I believe the first one creates a branch instruction. But what about the ternary operation? Does it become a branch on iPhone, too? Or iPhone's ARM has a evil opcode to do the job?

BTW, I also saw an evil technique like this:

a = (x > 0) * 1 + (x <= 0) * 2;

Is this really faster?


EDIT:

Just compiled your example, using GCC/LLVM, different optimizations, and looking at ARM6 and ARM7 assembly, here are my conclusions:

  • ARM-ASM differs depending on GCC / LLVM and target architecture
  • But, when using highest optimization level, it produce exactly the same assembly code for if and ternary, and that, whatever compiler/arch are. (yes, compared several pairs ;)

Here is the most concise result with LLVM / ARM7, using the IT instruction you mentionned, for if and ternary:

MOVS    R1, #2
CMP     R0, #0
IT GT
MOVGT   R1, #1
MOV.W   R2, #3
IT GT
MOVGT   R2, #4

ENDOFEDIT

Just searched a bit on the topic and even if some people thinks ternary is less optimized the most results and more relevant says that it produce the same assembly code.

Take care that it might change with :

  1. compiler GCC, LLVM...
  2. optimization level

I'm a bit lazy right now to disassemble code, but maybe I'll edit that answer later.

So I would think that djna is right, appart the the 2* (x>0), which would be really surprising if not optimized, this is the same.

After that, ternary or not, it is a matter of taste. I prefer ternary when it makes sense in code and is readable.

About second example it is a trick that use the fact that true == 1 / false == 0... Funny, but I wouldn't like to maintain that code.


No.

There are no winners at code golf.

Readability wins.

So in this case your first example using traditional conditional blocks is about 7099092034902 times easier to read. Anyone even remotely familiar with programming will be able to understand what is going on.

In the latter example... God, what is that!


A smart compiler could produce the same output for either code.

A non-smart compiler would result in that (X>0) being evaluated twice in the ternary operator case and therefore be slower!


Having spent years optimising software, I'd be willing to bet that the small block you post above isn't really your problem. I think we need to see the entire method together with some profiling results (when it comes to optimising, measuring is EVERYTHING) to get a better handle on it.

To answer your own question - take each option and profile it for say 10 million invocations (a mere thousand won't tell you anything much on the fragment above). That will tell you which is best for speed, there is no point in trying to second guess.


My question: in ARM level, which one is faster?

Why don't you write a simple test program that measures the execution speed for, say, 100000 invocations of each block?


There will be no difference, gcc will compile a simple if and a ternary operator into the same code. If you are really trying to optimize your code at the ARM asm level, then it is possible to get significant speedups by using conditional ARM asm code to avoid branching. But, in order to do that, you need to profile your code and figure out where it is really needed. Then, you would need to hand code ARM asm for only the hot spots in your code. Basically, if you don't need extreme performance improvements, then just use the compiler supplied features as the compiler does a good job in most cases.


Go for readability, you are not a compiler

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜