1つのページテンプレートでhome_url()
の複数のインスタンスを使用しているので、次の方法でページの読み込み時間が短縮されるのではないかと思いました。私の方法は、毎回home_url()
を使用するのではなく、毎回home_url()
の出力を変数に格納してから毎回その変数を呼び出すことです。
変数をエコーするとページの読み込み時間が速くなると私が思ったのは、(私の理解が正しければ)その変数を呼び出すたびにデータベースを照会する必要がないからです。
<ul>
<li><a href="<?php echo home_url(); ?>/category/blue">Blue Items</a></li>
<li><a href="<?php echo home_url(); ?>/category/green">Green Items</a></li>
<li><a href="<?php echo home_url(); ?>/category/red">Red Items</a></li>
<li><a href="<?php echo home_url(); ?>/category/orange">Orange Items</a></li>
<li><a href="<?php echo home_url(); ?>/category/purple">Purple Items</a></li>
<li><a href="<?php echo home_url(); ?>/category/gray">Gray Items</a></li>
</ul>
<?php $my_home_url = home_url(); ?>
<ul>
<li><a href="<?php echo $my_home_url; ?>/category/blue">Blue Items</a></li>
<li><a href="<?php echo $my_home_url; ?>/category/green">Green Items</a></li>
<li><a href="<?php echo $my_home_url; ?>/category/red">Red Items</a></li>
<li><a href="<?php echo $my_home_url; ?>/category/orange">Orange Items</a></li>
<li><a href="<?php echo $my_home_url; ?>/category/purple">Purple Items</a></li>
<li><a href="<?php echo $my_home_url; ?>/category/gray">Gray Items</a></li>
</ul>
home_url()
関数のソース を見ると、最終的にget_option()
を呼び出す小さな一連の関数呼び出しに気付くでしょう。 このWPSE Answer で説明されているように、get_option()
関数はキャッシュされます。つまり、オプションの値が既にメモリにある場合、get_option()
はデータベースを再度クエリする代わりにその値を返します。その結果、1回のリクエストでhome_url()
を1,000回呼び出した場合でも、データベースへのクエリは1回だけです。
メソッドB(ローカル変数の値を再利用する)には、メソッドA(必要に応じてhome_url()
を呼び出します)は、関数呼び出しの束を呼び出しスタックに循環させません。とはいえ、最新のPHPのパフォーマンスを考えると、その差はごくわずかであり、数ミリ秒単位で測定することができます。
要するに、メソッドBは、無限の尺度による場合に限り、常に代替ソリューションよりも優れたパフォーマンスを発揮します。
コメントで要求されているように、サーバー環境の両方のメソッドの実行時間プロファイルを作成しました。そうすることで、回答の最後に添付されたプラグインを作成しました。これを使用して、独自の環境でメソッドをテストできます。
私の環境( Vaging Vagrant Vagrants 'wordpress-default
サイト-PHP 5.4/MySQL 5.5/Nginx 1.4スタックを使用するUbuntu Server 12.04)、1000個のecho()
で平均100個のプロファイルインスタンスの場合、私は次の結果を受け取りました:
GET
文字列:?hup_method=a&hup_profiles=100&hup_instances=1000
100個のプロファイル全体で平均すると、メソッドAは0.023981981277466秒でhome_url()を1000回呼び出しました。
GET
文字列:?hup_method=b&hup_profiles=100&hup_instances=1000
100個のプロファイル全体で平均すると、メソッドBは0.00071162700653076秒で$ homeUrlへの1000回の参照をecho()しました。
このプロファイルでは、メソッドBはメソッドAよりも約34倍高速でした、メソッドBは0.7ミリ秒でecho()
'd 1000インスタンスを持ち、メソッドA管理されています。これは、home_url()
の呼び出しを実行するのに約23マイクロ秒(0.000023秒)かかり、$homeUrl
参照に従うのに0.7マイクロ秒(0.0000007秒)未満かかることを意味します(この時間の多くは、 home_url()
はMethod B)で使用されています。
コードのパフォーマンスの複雑さに非常に興味がある場合は、「Big O Notation」について学習するか、個別の数学コンピューターサイエンスコースを見つけることをお勧めします。
<?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 );
}
?>
GET
変数hup_method
を設定すると、指定された値に応じてメソッドAまたはBのプロファイルが実行されます。 GET
変数hup_instances
を使用して、プロファイル内のメソッドのエコーするホームURLの数を指定でき(デフォルトは1000)、変数hup_profiles
を使用して回数を指定できますプロファイルを実行して平均を作成したい(デフォルトは5)。
このプロファイルをより正確にするにはさまざまな方法があります(たとえば、for
ループを実行するのにかかる時間を減算します)が、現在の形式では、関係する時間枠のかなり良い一般的なアイデアを提供します。
乾杯!
あなたはあなたの仮定に絶対に正しいです。 wp-includes/link-template.php
のget_home_url()
の実際の定義を見てください。
余談:home_url()
は単にget_home_url()
をエコーする便利なメソッドです。
以下は関数定義です。その出力を変数に割り当てることで、このコードを必要以上に5回呼び出すことによるパフォーマンスへの影響を回避できます。
function get_home_url( $blog_id = null, $path = '', $scheme = null ) {
$orig_scheme = $scheme;
if ( empty( $blog_id ) || !is_multisite() ) {
$url = get_option( 'home' );
} else {
switch_to_blog( $blog_id );
$url = get_option( 'home' );
restore_current_blog();
}
if ( ! in_array( $scheme, array( 'http', 'https', 'relative' ) ) ) {
if ( is_ssl() && ! is_admin() && 'wp-login.php' !== $GLOBALS['pagenow'] )
$scheme = 'https';
else
$scheme = parse_url( $url, PHP_URL_SCHEME );
}
$url = set_url_scheme( $url, $scheme );
if ( $path && is_string( $path ) )
$url .= '/' . ltrim( $path, '/' );
return apply_filters( 'home_url', $url, $path, $orig_scheme, $blog_id );
}