StudioTime
StudioTime

Reputation: 23989

Is this ternary if efficient?

I am using a ternary if statement as I can't use switch for the following, but, is there a better way? I've read lately that these can be resource hungry? (this can be called multiple times within a page)

$filter= (
    ($price_check > '0' && $price_check < '20.01') ? '020' : 
    (($price_check > '20.00' && $price_check < '50.01') ? '2050' :
    (($price_check > '50.00' && $price_check < '100.01') ? '50100' :
    (($price_check > '100.00' && $price_check < '200.01') ? '100200' :
    (($price_check > '200.00' && $price_check < '500.01') ? '200500' :
    (($price_check > '500.00') ? '501' : '0'
))))));

Upvotes: 0

Views: 150

Answers (4)

Esoterica
Esoterica

Reputation: 133

(Yes I know this question is old but felt to add my own two cents into the mix.) While there are many ways to skin a cat. I felt to post some observations I made running numerous tests. You may also apply the same tests and/or apply them at http://3v4l.org/ (online PHP & HHVM Shell). To test you should run more than one to gauge the differences correctly. In the tests I took WebChemist's response and reversed it. Why? Sometimes just fun to play about. The actual result however showed there was a micro improvement in the ternary overall. Using various inputted values for both.

$price_check = '...';

$filter = (
    ( $price_check > '500') ? '501'     : 
    (($price_check > '200') ? '200-500' :
    (($price_check > '100') ? '100-200' :
    (($price_check > '50')  ? '50-100'  :
    (($price_check > '20')  ? '20-50'   :
    (($price_check > '0')   ? '0-20'    : 
    '0'
))))));

And then while the next example could be better improved, it is simply an example. So do not judge it as production level. It was just a thought between ternary and if/else. Overall the if/else performs better than either ternary applied. Mainly did this test because I always read on both ends, ternary is easier to read, or if/else is easier to read. I say both can be as provided in the below example. In the end I truly believe what you use one or the other for depends on the situation. As far as this data is concerned between filtering prices. The if/else ultimately won out over a ternary in speed. It is also fairly easy to read (I think). In the end its all micro jazz so it really doesn't matter all that much. Those who feel to disagree can run their own tests in their own environment, or go to the supplied website. Sometimes nicer than believing words across the internet. I ran many tests on my own environment, also that website, to come to some base conclusions. I still enjoy a good read with ternary and if/else arguments. Some good reads floating across the web. Also if dropping through really bugs you in the example. Past that it doesn't affect the performance, and even returns overall that with this code its faster. You can code in escapes, or restructure it entirely.

$price_check = '...';

    $filter='501';
    if($price_check > '500' || $filter='200-500')
    if($price_check > '200' || $filter='100-200')
    if($price_check > '100' || $filter='50-100' )
    if($price_check > '50'  || $filter='20-50'  )
    if($price_check > '20'  || $filter='0-20'   )
    if($price_check <= '0') $filter=0;

I would like to add that Jon's suggestion of a array is probably the best one, if the data is of a moderate size. Ternary and if/else can handle most basic nests. A list is recommended on moderate. Anything more should be pushed to a database and accessed. Additionally I fixed Jon's code slightly. (If you deeply nest ternary and if/else over a database there's something wrong with you.)

$data = '20.00';
$range = '';

$arr = [
    '0',
    '20'  => '0-20',
    '50'  => '20-50',
    '100' => '50-100',
    '200' => '100-200',
    '500' => '200-500'
];

foreach ($arr as $floor => $value) {
    $range = $value;
    if ($floor >= $data)break;
} echo $range;

Upvotes: 0

WebChemist
WebChemist

Reputation: 4411

Just wanted to point out that you can simplify your range check, having lower bounds on each "elseif" is unnecessary, because if it had matched it wouldnt be calling the next test condition:

$filter = (
     $price_check <= 0   ? '0' :
    ($price_check <= 20  ? '020' : 
    ($price_check <= 50  ? '2050' :
    ($price_check <= 100 ? '50100' :
    ($price_check <= 200 ? '100200' :
    ($price_check <= 500 ? '200500' : 
    '501'
))))));

Upvotes: 2

Jon
Jon

Reputation: 437554

Talking about "efficiency" of the ternary operator is a red herring. It doesn't matter how fast it is, and it likely still wouldn't matter if the code were placed inside the inner loop of a compute-bound application (which this is almost certainly not).

What you should be asking is "do I want to find this in front of me six months later when I need to make a change?".

Maintainability should always come first as a rule of thumb. If you don't know for a fact that this code really is a bottleneck, you should write it as conveniently as possible.

So you might consider alternative styles that are less performant but much more maintainable, such as:

$data = array(
    '0'      => '020',
    '20.00'  => '2050',
    '50.00'  => '50100',
    // ...
);

$price_check = '...';
$filter = '0'; // default value
foreach ($data as $floor => $value) {
    if ($floor > $price_check) break;
    $filter = $value;
}

Upvotes: 8

Dacav
Dacav

Reputation: 14078

In today's computing, unless you are working in the Embedded System field, human time is by far more valuable than computer time: a computer will take a few nanoseconds either ways, and the bottleneck will be somewhere else (more likely in the network transmission). You should instead ask yourself if the code, written in that way, is more easy for you to understand or not.

Also keep in mind that a statement which today is not efficient, tomorrow could be better, as the language gets improved.

Upvotes: 2

Related Questions