web-dev-qa-db-fra.com

Utilisation de plusieurs requêtes de "home_url" et appel d'une variable plusieurs fois

Question

Étant donné que j'utilise plusieurs instances de home_url() dans un modèle de page, j'étais curieuse de savoir si la méthode suivante accélérerait le temps de chargement de la page. Ma méthode consiste à stocker la sortie de home_url() dans une variable, puis à appeler cette variable à chaque fois, plutôt que d'utiliser home_url() à chaque fois.

Motivation

La raison pour laquelle je pensais que l'écho d'une variable serait d'accélérer le temps de chargement de la page est dû au fait que (si ma compréhension est bonne) l'écho d'une variable ne nécessiterait pas d'interroger la base de données, chaque fois que j'appellerais cette variable.

Méthode A

<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>

Méthode b

<?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>
1
Ademos

Si vous regardez la source de la fonction home_url() , vous remarquerez une petite série d'appels de fonction appelant finalement get_option(). Comme expliqué dans cette réponse WPSE , la fonction get_option() est mise en cache, ce qui signifie que si la valeur d'une option est déjà en mémoire, get_option() renvoie cette valeur au lieu d'interroger le base de données à nouveau. Par conséquent, même si vous appelez home_url() mille fois au cours d'une requête, la requête ne sera interrogée qu'une seule fois.

Cela dit, la méthode B (réutiliser la valeur d’une variable locale) présente toujours un léger avantage en termes de performances par rapport à La méthode A (appelant home_url() comme nécessaire) en ce sens qu’il ne programme pas un tas d’appels de fonction sur la pile d’appels. Cela dit, étant donné les performances modernes de PHP, la différence est négligeable et peut être mesurée en plusieurs millisecondes, à moins que la microseconde ne permette de décrire les différentes approches.

En bref, la méthode B sur-performera toujours les solutions alternatives, ne serait-ce que par une mesure infinitésimale.

Addenda

Comme demandé dans les commentaires, j'ai créé des profils de temps d'exécution des deux méthodes pour mon environnement de serveur. Ce faisant, j'ai créé le plug-in attaché au bas de ma réponse, que vous pouvez utiliser pour tester les méthodes dans votre propre environnement.

Dans mon environnement ( Variables vagabonds variables 'wordpress-default site - Ubuntu Server 12.04 utilisant une pile PHP 5.4/MySQL 5.5/Nginx 1.4) , avec une moyenne de 100 profils avec 1000 echo() 'd instances, j’ai reçu les résultats suivants:

Méthode A

GET chaîne: ?hup_method=a&hup_profiles=100&hup_instances=1000

En moyenne sur 100 profils, la méthode A echo () contient 1 000 appels à home_url () en 0.023981981277466.

Méthode b

GET chaîne: ?hup_method=b&hup_profiles=100&hup_instances=1000

En moyenne sur 100 profils, méthode B echo () 'd 1000 références à $ homeUrl en 0,00071162700653076 secondes.

Dans ce profil, la méthode B était environ 34 fois plus rapide que la méthode A , la méthode B ayant echo() ' d 1000 instances en 0,7 millisecondes, 23,2 millisecondes plus rapidement que Méthode A gérée. Cela signifie qu'il a fallu environ 23 microsecondes (0,000023 seconde) pour exécuter un appel à home_url() et moins de 0,7 microsecondes (0,0000007 seconde) pour suivre une référence $homeUrl (une grande partie de ce temps peut être attribué à l'appel initial à home_url() utilisé dans Méthode B ).

Si vous êtes extrêmement intéressé par les complexités de la performance du code, je vous recommande de passer un peu de temps à apprendre la "notation Big O" ou à trouver un cours d'informatique mathématique discret.

<?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 );
}

?>

La définition de la variable GEThup_method exécute un profil pour la méthode A ou B en fonction de la valeur spécifiée. La variable GEThup_instances peut être utilisée pour spécifier le nombre d'URL de base à afficher pour la méthode dans un profil (la valeur par défaut est 1000), et la variable hup_profiles peut être utilisée pour spécifier le nombre de fois que vous souhaitez exécuter le profil pour le créer. une moyenne (5 par défaut).

Ce profil peut être rendu plus précis de différentes manières (en soustrayant le temps nécessaire pour exécuter la boucle for, par exemple), mais dans sa forme actuelle, il donne une assez bonne idée générale des délais impliqués.

À votre santé!

2
bosco

Vous avez absolument raison dans votre hypothèse. Regardez la définition actuelle de get_home_url() dans wp-includes/link-template.php.

à part: home_url() est simplement une méthode pratique qui fait écho à get_home_url().

Ci-dessous, la définition de la fonction. En affectant sa sortie à une variable, vous évitez l'impact sur les performances d'appeler ce code 5 fois plus que nécessaire:

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 );
}
0
Cameron Hurd