![]() Join Up! 96812 members and counting! |
|
|||
Timing Script Execution
Allan Kent
Timing Script Execution
No doubt you've all seen on Google's search page where it tells you how long your
search took to complete. This, and some talk I noticed a while back in one of the
forums about some of the scripts that were taking a while to execute made me think
about how you would go about timing your scripts.
The easiest way of timing a script would be to get the time at the beginning of the
script and then get the time at the end of the script. The difference between the
two is the time it took your script to run. PHP has a function time() which returns
the number of seconds since 1970. Now I can't speak for everyone here, but typically
the scripts that I write tend to finish running within a second. So measuring the
time in seconds is not really going to help me. A topical example would be using
something like an egg timer to time the 100m Olympic final - unless someone breaks
both their legs on the starting blocks, all the runners will be within 1 egg timer.
The microtime() function gives us what we need - the fractional part of the second
at the time that the function was called. It also gives us the number of seconds since
1970 like time() does, so we don't need to call both functions. The only problem with
the microtime() function is that it returns to us a string with 2 numbers in it - the
seconds part, and the fractional part - separated by a space.
<?php
Returns:
0.13554500 968578758
This is not all that useful to us when trying to work out differences, so what we need
to do is drop the 0 from the front of the fractional part and tack the rest onto the end of the seconds part:
Both the explode() and substr() functions are well documented in the manual and have been dealt with on numerous occasions on this site, so I'm not going to waste time going through them here again.
Once we have 2 times (a start and finish) we can subtract the start time from the finish time and we'll have the difference. If you use the bcsub() function, remember to indicate to the function how many places after the decimal point you want to preserve. If you don't, then it'll default to integers and you'll be back in the egg timer scenario again.
returns to us
0.000457
You can now pop that code in amongst your script to debug what's taking so long in your script.
Getting Clever
The problem with the previous script is that what happens when you want to find exactly which part of your script is taking all the time? You have to move the start time and end time bits around all over the script and write down the results, comparing notes and invariably losing half the little bits of paper you wrote them down on. What if we want to create markers all the way through our script and see the time it takes between each marker? Sounds like a lot code to add into our scripts, so what I did instead was create a timer object, which we could use to time our scripts.
The timer object
Our object will only need one property - an array of the times that we have marked parts of the script. I also added in a descriptor for the time. Our object will have to have a number of methods - a method to start the timer, a method to stop the timer and a method to add markers for any points in between. We will also need a method to display the information that we have collected. Because I found that a lot the code was being duplicated, I created a function to join the times together.
Here then is the code for the include file phptimer.inc. I've added comments through the code as explanation, but if you are happy with arrays and understand a bit of OO programming, you should have no worries:
My PHP script to use this object now looks like this:
and will return to me something like:
Script execution debug information:
Last Word
I've intended this script to be a quick and easy way for programmers to debug lock ups
and timing problems in their scripts. Therefore I haven't included any error checking
code. Also use a bit of common sense about where you put markers in your code - inside
a loop that is iterating through a database is probably not a good idea. Once before
and one after the loop would be a better idea.
I have started working on some ways of improving the debug information and output with
graphs and being able to nest or group markers, but this should be a start on debugging your scripts.
-Allan
|