Enum usecases: Profiling

at 2007-07-29 in Examples by friebe (0 comments)

As you might now, from time to time, I investigate PHP language features on their performance. Examples include if / elseif vs. if / else if (no difference), testing control structures (switch vs. if / else cascades vs. the ternary operator - if / else cascades are the fastest, see entry #179) or whether default arguments have an impact (none).

What I did to compare these was to create a class for each strategy, use reflection to load it depending on the command line argument passed and then run it, printing out profiling information gathered via util.profiling.Timer. See here for an example.

The downsides of this approach were:

  • There was no way to run all strategies at once
  • Every strategy I added needed to be manually added to the usage
  • The profiling / runner sourcecode was copied every time

While searching for alternatives, I came up with a nice solution using enums (see also entry #200).

Overview
The classes in use are the following:

  • Profile
    An xpcli-runnable which generically allows to run profiling tests on a certain number of usecases.
  • Profileable
    An interface denoting a certain enumeration is profileable - that is, it contains a public run($times) method
  • The implementation itself
    The class containing the use cases must be an abstract enum and implement the Profileable interface. Its members contain the sourcecode for the respective usecases.


The implementation
To create a profileable enum for usage within the profiler, you can use the following skeleton (written in XP language sourcecode to improve readability):
  abstract enum UseCases implements Profileable {
ONE
{
public void run
(int $times) {
// Use case #1 implementation here
}
},
TWO
{
public void run
(int $times) {
// Use case #2 implementation here
}
}
}

The enum members' sourcecode must consist of a for loop which iterates $times times, executing the test to be profiled:
  for ($i= 0; $i < $times; $i++) {
// Put whatever should be profiled here
}
This does not conform to the DRY principle but ensures we are not measuring anything else than the profiled source and the negligible overhead of the for loop.

For a complete example, have a look at the MethodCalls Enum (please note that the sourcecode there might look quite confusing at first - this is mainly due to the restrictions in the PHP language also described in RFC #0132).

Running the profilee
There are two ways to run the profilee - by supplying the enum class, all members are tested:
  $ xpcli Profile MethodCalls
public: 0.828 seconds for 100000 calls
private: 0.842 seconds for 100000 calls
protected: 0.881 seconds for 100000 calls
By adding :: and the use case's name, a single use case can be run:
  $ xpcli Profile MethodCalls::public
public: 0.831 seconds for 100000 calls

Summing it up
This article has shown a nice use-case for enums in my opinion - it is easy to extend them by simply adding an enum member to the profileable enum's declaration. Because of the generic way the Profile class is implemented, the only thing needed to create a new collection of usecases it to create a new enum according to the rules described above.

Happy profiling:)



Subscribe

You can subscribe to the XP framework's news by using RSS syndication.


Categories

News
General
PHP5
Announcements
RFCs
Further reading
Examples
Editorial
EASC
Experiments
Unittests
Databases
5.8-SERIES
Unicode
Language
5.9-SERIES

Related

Find related articles by a search for «Enum».