Calling a constant should always be faster than a function call, right? PHP contains two different ways to get the directory that a file is currently in.
__DIR__ is a magic constant added to PHP in 5.3. The official PHP documentation specifically states: “This is equivalent to
dirname(__FILE__).” Equivalent in return doesn’t necessarily mean equivalent in performance though, so I decided to test the performance of both accross a couple of variables.
When running lots of tests, I’ve found that travis-ci can be a big helper. You can define the matrix of the tests you want to run as your testing matrix and then use the results. So I setup a repo for my tests. The repo contains four main pieces:
- A file generator which creates the code I’ll actually run the performance test on.
- A test running script which runs the actual tests.
- The travis.yml file to define my tests matrix
- Files used for the actual test. This is not linked, there are 400,000 files. The generator shows them off.
My test calls the function I am looking for 100,000 each. One run has all the files in 1 directory, and the other has one file per directory. I wanted to rule out the possibility that a single directory could affect this call.
I ran this test on six version of PHP: 5.6.40, 7.0.33, 7.1.27, 7.2.15, 7.3.9 and 7.4-dev. Each test did 650 runs and I looked at the user time for each of those runs. This means that I called both
dirname( __file__ ) 130,000,000 times each. I then took the times for each of these runs and looked at that maximum (slowest) run for each and the 95% time ( the average between the 618th and 619th slowest) to rule out any extreme cases. Overall, the results between maximum and 95% are similar.
User is the amount of CPU time spent in user-mode code (outside the kernel) within the process. This is only actual CPU time used in executing the process. Other processes and time the process spends blocked do not count towards this figure.Stack Overflow
dirname( __FILE__) Test Results
|dir ( 1 folder)||1.4||2.76||2.08||2.51||2.27||1.3615|
|dir ( many folders)||1.38||2.29||2.55||2.3615||2.65||1.57|
|dirname( 1 folder)||1.5815||2.27||2.7415||3.24||2.41||1.5215|
|dirname( many folders)||1.68||2.29||2.0815||3.29||2.6815||1.87|
Overall, the results show that
__dir__ is generally faster, but it’s rarely much faster. Consider that in the slowest run ( using PHP 7.2 and calling
dirname( __FILE__ ) on multiple folders), each call took 0.0000329 seconds. The fastest run was 2 hundred-thousandths of a second faster. This is such a micro optimization that except under extreme scale, it’s unlikely you will ever notice a difference. That said, under most versions of PHP,
__DIR__ is faster.
At the end of the day, the performance of
__DIR__ is ever so slightly better, but more importantly I think it’s clearer and easier to read. So I’m on team
__dir__, but the performance is only a bonus.
If you have a different thought, or think that my testing methodology could be improved, please let me know in the comments below.