If you look at the source for the home_url()
function, you’ll note a small series of function calls eventually invoking get_option()
. As explained in this WPSE Answer, the get_option()
function is cached, meaning that if an option’s value is already in memory, get_option()
returns that value instead of querying the database again. As a result, even if you call home_url()
a thousand times during one request it will only query the database once.
That in mind, Method B (re-using the value from a local variable) still has a slight performance advantage over Method A (calling home_url()
as needed) in that it doesn’t cycle a bunch of function calls onto the call stack. That said, given modern PHP’s performance, the difference is negligible and could be measured in a number of milliseconds, if not microseconds were one to profile the different approaches.
In short, Method B will always out-perform alternate solutions, if only by an infinitesimal measure.
Addendum
As requested in the comments, I have created execution time profiles of both methods for my server environment. In doing so, I created the plugin attached to the bottom of my answer, which you can use to test the methods in your own environment.
In my environment (Varying Vagrant Vagrants‘ wordpress-default
site – Ubuntu Server 12.04 using a PHP 5.4/MySQL 5.5/Nginx 1.4 stack), averaging 100 profiles with 1000 echo()
‘d instances, I received the following results:
Method A
GET
string: ?hup_method=a&hup_profiles=100&hup_instances=1000
Averaged across 100 profiles, Method A echo()’d 1000 calls to home_url() in 0.023981981277466 seconds.
Method B
GET
string: ?hup_method=b&hup_profiles=100&hup_instances=1000
Averaged across 100 profiles, Method B echo()’d 1000 references to $homeUrl in 0.00071162700653076 seconds.
In this profile, Method B was about 34 times faster than Method A, Method B having echo()
‘d 1000 instances in 0.7 milliseconds, 23.2 milliseconds faster than Method A managed. This means that it took approximately 23 microseconds (0.000023 seconds) to execute a call to home_url()
, and less than 0.7 microseconds (0.0000007 seconds) to follow a $homeUrl
reference (much of this time can be attributed to the initial call to home_url()
used in Method B).
If you’re super interested in the complexities of code performance, I recommend spending some time learning about “Big O Notation,” or finding a discrete mathematics computer science course.
<?php
/*
Plugin Name: Home URL Method Profiler
Plugin URI: https://wordpress.stackexchange.com/questions/136091
Description: Using Multiple Queries of “home_url” vs. Calling a Variable Multiple Times
Version: 0.1
Author: Adam Bosco
Author URI: https://wordpress.stackexchange.com/users/25324
License: GPL2
*/
class HomeUrlProfile {
private static $hasPrinted = false; // Only print out the results once
private static $method = NULL; // The method to profile
private static $executionTimes = []; // Profile results.
private static $instanceCount = 1000; // Number of instances of calls to home_url() or uses of $homeUrl to profile against
private static $profileCount = 5; // Number of times to run the same profile
// Constructor; set up action hooks.
public function HomeUrlProfile( $method ) {
self::$method = strtolower( $method );
if( isset( $_GET[ 'hup_instances' ] ) )
self::$instanceCount = $_GET[ 'hup_instances' ];
if( isset( $_GET[ 'hup_profiles' ] ) )
self::$profileCount = $_GET[ 'hup_profiles' ];
add_action( 'init', 'HomeUrlProfile::run' );
add_action( 'loop_start', 'HomeUrlProfile::printResults' );
}
// Perform a profile
public static function run() {
// Perform the same profile of a method with the same number of echo()'d instances $profileCount times
for( $i = 0; $i < self::$profileCount; $i++ ) {
/* For a more realistic scenario, we'll actually echo the home URL for each
* iteration. In order to avoid actually displaying all those URLs, we'll
* capture the output in a buffer, then discard it after we get our execution
* times. */
ob_start();
// Run the requested method and push the results to the $executionTimes array;
if( self::$method == 'a' )
array_push( self::$executionTimes, self::methodA() );
else
array_push( self::$executionTimes, self::methodB() );
// Clear the output buffer.
ob_end_clean();
// Remove home_url()'s cached values after each profile.
wp_cache_delete( 'home', 'option' );
wp_cache_delete( 'alloptions', 'options' );
}
}
public static function printResults() {
if( self::$hasPrinted )
return;
self::$hasPrinted = true;
$averageTime = array_sum( self::$executionTimes ) / self::$profileCount;
?>
<div>
<h3>Home URL "Method <?php echo strtoupper( self::$method ); ?>" Profile Results</h3>
<p>Averaged across <?php echo self::$profileCount; ?> profiles, Method <?php echo strtoupper( self::$method ); ?> echo()'d <?php echo self::$instanceCount; echo( self::$method == 'a' ? ' calls to home_url()' : ' references to $homeUrl' ); ?> in <?php echo $averageTime; ?> seconds.</p>
<ol><?php
foreach( self::$executionTimes as $executionTime ) {
echo('
<li>' . $executionTime . ' seconds</li>');
}
?></ol>
</div>
<?php
}
// "Method A" - using multiple calls to home_url().
public static function methodA() {
// Record the UNIX timestamp as a floating-point value before execution.
$startTime = microtime( true );
for( $i = 0; $i < self::$instanceCount; $i++ ) {
echo( home_url() );
}
// Record the UNIX timestamp after execution
$endTime = microtime( true );
// Return the difference between the timestamps
return $endTime - $startTime;
}
public static function methodB() {
// Record the UNIX timestamp as a floating-point value before execution.
$startTime = microtime( true );
$homeUrl = home_url();
for( $i = 0; $i < $instanceCount; $i++ ) {
echo( $homeUrl );
}
// Record the UNIX timestamp after execution
$endTime = microtime( true );
// Return the difference between the timestamps
return $endTime - $startTime;
}
}
if( ! isset( $HomeUrlProfile ) && isset( $_GET[ 'hup_method' ] ) ) {
$method = strtolower( $_GET[ 'hup_method' ] );
switch( $method ) {
case 'a':
case 'b':
break;
default:
die( 'Invalid Home URL profiling method specified (must be \'A\' or \'B\'): ' . $_GET[ 'hup_method' ] );
}
$HomeUrlProfile = new HomeUrlProfile( $method );
}
?>
Setting the GET
variable hup_method
will run a profile for method A or B depending on the value specified. The GET
variable hup_instances
can be used to specify the number of home URLs to echo for the method in a profile (defaults to 1000), and the variable hup_profiles
can be used to specify the number of times you would like to run the profile to create an average (defaults to 5).
There are various ways in which this profile could be made more accurate (subtracting the amount of time it takes to perform the for
loop, for instance), but in it’s present form it gives a pretty good general idea of the timeframes involved.
Cheers!