Forum Discussion
smp_86112
Cirrostratus
Jun 24, 2010Optimizing If statement conditions
I see this examples like this all over the place:
when HTTP_REQUEST {
if { [HTTP::host] equals "www.myhost.com" and [HTTP::uri] equals "/myuri" } {
HTTP::redirect https://[HTTP::host][HTTP::uri]
}
}I am going though a large number of iRules in an attempt to optimize, and I had a thought occur to me while looking at one of mine like this. Shouldn't I be able to consolidate these two conditions into one, and wouldn't it be more efficient? Something like this?
when HTTP_REQUEST {
if { [[HTTP::host][HTTP::uri]] equals "www.myhost.com/myuri" } {
HTTP::redirect https://[HTTP::host][HTTP::uri]
}
}As a practical matter, this iRule generates an error when it is triggered:TCL error: www.myhost.com - invalid command name "www.myhost.com/myuri" while executing "[HTTP::host][HTTP::uri]"
Assuming I can figure out how to properly write this condition (please help???), wouldn't this be more efficient than writing two conditions to evaluate and then compare? If I can get the syntax right, I'll test it out.
14 Replies
- Another optimization technique that is often forgotten is to omit all code that always succeeds. If, for instance, the host on the virtual is always www.myhost.com (the virtual isn't multi-hosting domains), then leaving that check out completely wouldn't be a bad idea. In this case, it would be faster to build multiple iRules to run with different virtuals, than building a single iRule you could apply to mutliple virtuals. It would be more to maintain, but it would be faster.
Good point for Jason on the "string tolower" checks. That is almost always done on the URI but isn't needed on the host header.
-Joe - smp_86112
Cirrostratus
Yes, both Jason and hoolio bring up points I didn't consider. It seems this consolidation idea is only useful in pretty limited circumstances. Here are the results of my testing when forcing the string to lowercase (sorry for the long delay). It seems that adding the string tolower statement reversed the results. Does that make sense to you?
timing on when HTTP_REQUEST { if { [string tolower [HTTP::host][HTTP::uri]] equals "www.myhost.com/admin" } { HTTP::uri "/new_uri" } } ltm rule-event { aborts 0 avg-cycles 14762 event-type HTTP_REQUEST failures 0 max-cycles 146684 min-cycles 0 name www.myhost.com priority 500 total-executions 100017 } ltm rule-event { aborts 0 avg-cycles 14892 event-type HTTP_REQUEST failures 0 max-cycles 121975 min-cycles 0 name www.myhost.com priority 500 total-executions 100010 } ltm rule-event { aborts 0 avg-cycles 14804 event-type HTTP_REQUEST failures 0 max-cycles 160099 min-cycles 0 name www.myhost.com priority 500 total-executions 100014 } timing on when HTTP_REQUEST { if { [HTTP::host] equals "www.myhost.com" and [string tolower [HTTP::uri]] equals "/admin" } { HTTP::uri "/new_uri" } } ltm rule-event { aborts 0 avg-cycles 14466 event-type HTTP_REQUEST failures 0 max-cycles 89955 min-cycles 0 name www.myhost.com priority 500 total-executions 100014 } ltm rule-event { aborts 0 avg-cycles 14457 event-type HTTP_REQUEST failures 0 max-cycles 129122 min-cycles 0 name www.myhost.com priority 500 total-executions 100020 } ltm rule-event { aborts 0 avg-cycles 14129 event-type HTTP_REQUEST failures 0 max-cycles 156109 min-cycles 0 name www.myhost.com priority 500 total-executions 100021 } - hoolio
Cirrostratus
I think that's just down to the extra few cycles it takes to handle a longer string that's being set to lower case:
% set str ABCDEFGHIJKLMNOPQRSTABCDEFGHIJKLMN...
% string length $str
1000
% time {string tolower $str} 1000
79 microseconds per iteration
% set smaller_str [string range $str 100 end]
% time {string tolower $smaller_str} 1000
65 microseconds per iteration/
Though in theory you should set the Host value to lower case in order to check it. RFC2616 states that the Host evaluation must be done case-insensitively. In practice, I think all major browsers set the host to lowercase before sending the request anyhow.
Aaron - smp_86112
Cirrostratus
You are absolutely right hoolio. I did the test again, this time setting the strings to lowercase in both conditions. It seems the consolidated statement is still faster, and the difference is a bit wider in this case. I won't post the whole thing anymore, just the avg-cycles:timing on when HTTP_REQUEST { if { [string tolower [HTTP::host][HTTP::uri]] equals "www.myhost.com/admin" } { HTTP::uri "/new_uri" } } avg-cycles 14762 avg-cycles 14892 avg-cycles 14804timing on when HTTP_REQUEST { if { [string tolower [HTTP::host]] equals "www.myhost.com" and [string tolower [HTTP::uri]] equals "/admin" } { HTTP::uri "/new_uri" } } avg-cycles 16219 avg-cycles 16526 avg-cycles 16626
Recent Discussions
Related Content
DevCentral Quicklinks
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com
Discover DevCentral Connects
