views:

101

answers:

5

I am currently building an internal tool to be used by our management to control the flow of traffic. I have built an if/then interface allowing the user to set conditions for certain outcomes, however it is inefficient to use the switch statement to control the flow. How can I improve the efficiency of my code? Example of code:

            if($previous['route_id'] == $condition['route_id'] && $failed == 0) //if we have not moved on to a new set of rules and we haven't failed yet
        {   
            switch($condition['type'])
            {
                case 0 :
                    $type = $user['hour'];
                break;
                case 1 :
                    $type = $user['location']['region_abv'];
                break;
                case 2 :
                    $type = $user['referrer_domain'];
                break;
                case 3 :
                    $type = $user['affiliate'];
                break;
                case 4 :
                    $type = $user['location']['country_code'];
                break;
                case 5 :
                    $type = $user['location']['city'];
                break;
            }
            $type = strtolower($type);
            $condition['value'] = strtolower($condition['value']);

            switch($condition['operator'])
            {
                case 0 :
                    if($type == $condition['value']);
                    else $failed = '1';
                break;
                case 1 :
                    if($type != $condition['value']);
                    else $failed = '1';
                break;
                case 2 :
                    if($type > $condition['value']);
                    else $failed = '1';
                break;
                case 3 :
                    if($type >= $condition['value']);
                    else $failed = '1';
                break;
                case 4 :
                    if($type < $condition['value']);
                    else $failed = '1';
                break;
                case 5 :
                    if($type <= $condition['value']);
                    else $failed = '1';
                break;
            }
        }
+1  A: 

One way to tweak it a bit is to determine what conditions are most likely to occur and put those options at the top of the if/then so you don't have to fall through far before a TRUE evaluation occurs. The less checks you have to make, obviously the quicker/more efficient it will be.

Thyamine
A: 
case 0 :
      if($type == $condition['value']);
      else $failed = '1';
      break;

Although from an execution efficiency point of view it won't make a difference, you might try inverting your logic to make the intentions more readable.

case 0 :
    $success = ($type == $condition['value']);
    break;

and of course, update your controlling condition:

$success = true;   // you probably want to start off optimistic ($success is bool)
...
if($previous['route_id'] == $condition['route_id'] && $success)
...
dar7yl
A: 

In essence, what you have here is a Finite-State-Machine (FSM). You might want to write a parser for your rules, which creates a network (graph) structure containing each element as a single object, connected to the other objects (ie routes). Each element would then have an (overloaded) function which can access the required parameters and operators directly.

There are a number of tools (google it) you can use that can generate state machines for you, or you can grow your own language and engine.

dar7yl
A: 

If there's any one of those cases that's way more probable to happen then you could make it bias towards that.. it'll at least make it more efficient for for that case (rather ugly though). Just my $0.02

Kalle Herler
A: 

The way that I solved this issue was actually quite simple. When the if/then rules are created, PHP automatically generates a PHP script with all the if/then scenarios written out in code. Then PHP just loads that file and executes it. Quite simple =)

Brendan