【问题标题】:Why i do not gain performance using ClassMapAutoloader in Zend Framework 2?为什么在 Zend Framework 2 中使用 ClassMapAutoloader 没有获得性能?
【发布时间】:2015-08-18 14:55:45
【问题描述】:

在我的公司,我们正在开发一个 ZF2 应用程序,没有程序;-),现在。我们正处于一个阶段,我们希望通过将应用程序的某些部分公之于众来测试它。

我们准备了一个 STAGE 环境,我现在进行一些性能调整。我读到使用ClassMapAutoloaderStandardAutoLoader 快得多,例如描述的。 http://samminds.com/2012/11/zf2-performance-quicktipp-2-classmap-autoloading/ 。我确实理解为什么它应该更快,但在我的情况下,我使用 xdebug 分析、WinCacheGring/QCacheGrind 分析了有和没有 ClassMapAutoloader 的站点,它较慢约为 0.2%。

有谁知道为什么这会变慢?

我使用的是 CentOS 和 PHP 版本 => 5.6.12

编辑添加信息:

一个autoload_classmap.php的例子:

    <?php
// Generated by ZF2's ./bin/classmap_generator.php
return array(
    'Search\Elasticsearch\Document\AbstractDocument'          => __DIR__ . '/src/Search/Elasticsearch/Document/AbstractDocument.php',
    'Search\Elasticsearch\Document\ArticleDocument'           => __DIR__ . '/src/Search/Elasticsearch/Document/ArticleDocument.php',
    'Search\Elasticsearch\Document\BookingDocument'           => __DIR__ . '/src/Search/Elasticsearch/Document/BookingDocument.php',
    'Search\Elasticsearch\Document\DocumentType'              => __DIR__ . '/src/Search/Elasticsearch/Document/DocumentType.php',
    'Search\Elasticsearch\Document\InvoiceDocument'           => __DIR__ . '/src/Search/Elasticsearch/Document/InvoiceDocument.php',
    'Search\Elasticsearch\Document\OfficeDocument'            => __DIR__ . '/src/Search/Elasticsearch/Document/OfficeDocument.php',
    'Search\Elasticsearch\Document\OfficeMemberDocument'      => __DIR__ . '/src/Search/Elasticsearch/Document/OfficeMemberDocument.php',
    'Search\Elasticsearch\Document\ProductDocument'           => __DIR__ . '/src/Search/Elasticsearch/Document/ProductDocument.php',
    'Search\Elasticsearch\Document\ProfileDocument'           => __DIR__ . '/src/Search/Elasticsearch/Document/ProfileDocument.php',
    'Search\Elasticsearch\Document\RatingDocument'            => __DIR__ . '/src/Search/Elasticsearch/Document/RatingDocument.php',
    'Search\Elasticsearch\Document\AbstractWebSearchDocument' => __DIR__ . '/src/Search/Elasticsearch/Document/AbstractWebSearchDocument.php',
    'Search\Elasticsearch\AutoSuggestionQueryHandler'         => __DIR__ . '/src/Search/Elasticsearch/AutoSuggestionQueryHandler.php',
    'Search\Elasticsearch\SearchStatisticIndexHandler'        => __DIR__ . '/src/Search/Elasticsearch/SearchStatisticIndexHandler.php',
    'Search\Elasticsearch\TermRecognizerQueryHandler'         => __DIR__ . '/src/Search/Elasticsearch/TermRecognizerQueryHandler.php',
    'Search\Elasticsearch\SearchIndexHandler'                 => __DIR__ . '/src/Search/Elasticsearch/SearchIndexHandler.php',
    'Search\Elasticsearch\SearchQueryHandler'                 => __DIR__ . '/src/Search/Elasticsearch/SearchQueryHandler.php',
    'Search\Elasticsearch\TermRecognizerIndexHandler'         => __DIR__ . '/src/Search/Elasticsearch/TermRecognizerIndexHandler.php',
    'Search\Exception\Exception'                              => __DIR__ . '/src/Search/Exception/Exception.php',
    'Search\Factory\AutoSuggestQueryHandlerFactory'           => __DIR__ . '/src/Search/Factory/AutoSuggestQueryHandlerFactory.php',
    'Search\Factory\AutoSuggestServiceFactory'                => __DIR__ . '/src/Search/Factory/AutoSuggestServiceFactory.php',
    'Search\Factory\DocumentStorerServiceFactory'             => __DIR__ . '/src/Search/Factory/DocumentStorerServiceFactory.php',
    'Search\Factory\QueueWorkerServiceFactory'                => __DIR__ . '/src/Search/Factory/QueueWorkerServiceFactory.php',
    'Search\Factory\SearchIndexHandlerFactory'                => __DIR__ . '/src/Search/Factory/SearchIndexHandlerFactory.php',
    'Search\Factory\SearchQueryHandlerFactory'                => __DIR__ . '/src/Search/Factory/SearchQueryHandlerFactory.php',
    'Search\Factory\SearchServiceFactory'                     => __DIR__ . '/src/Search/Factory/SearchServiceFactory.php',
    'Search\Factory\SearchSimpleServiceFactory'               => __DIR__ . '/src/Search/Factory/SearchSimpleServiceFactory.php',
    'Search\Factory\SearchStatistikIndexHandlerFactory'       => __DIR__ . '/src/Search/Factory/SearchStatistikIndexHandlerFactory.php',
    'Search\Factory\TermRecognizerServiceFactory'             => __DIR__ . '/src/Search/Factory/TermRecognizerServiceFactory.php',
    'Search\Factory\TermrecognizerIndexHandlerFactory'        => __DIR__ . '/src/Search/Factory/TermrecognizerIndexHandlerFactory.php',
    'Search\Factory\TermrecognizerQueryHandlerFactory'        => __DIR__ . '/src/Search/Factory/TermrecognizerQueryHandlerFactory.php',
    'Search\Factory\RequestHandlerFactory'                    => __DIR__ . '/src/Search/Factory/RequestHandlerFactory.php',
    'Search\Logger\LoggerInterface'                           => __DIR__ . '/src/Search/Logger/LoggerInterface.php',
    'Search\Logger\StatisticLogger'                           => __DIR__ . '/src/Search/Logger/StatisticLogger.php',
    'DatabaseQueue'                                           => __DIR__ . '/src/Search/Queue/DatabaseQueue.php',
    'Search\Search\QueryWordReducer'                          => __DIR__ . '/src/Search/Search/QueryWordReducer.php',
    'Search\Search\RecognizedTermConsumer'                    => __DIR__ . '/src/Search/Search/RecognizedTermConsumer.php',
    'Search\Search\SearchService'                             => __DIR__ . '/src/Search/Search/SearchService.php',
    'Search\Search\SuggestionListBuilder'                     => __DIR__ . '/src/Search/Search/SuggestionListBuilder.php',
    'Search\Search\Util'                                      => __DIR__ . '/src/Search/Search/Util.php',
    'Search\Search\ViewState'                                 => __DIR__ . '/src/Search/Search/ViewState.php',
    'Search\Search\ViewStateToSearchRequestTransformer'       => __DIR__ . '/src/Search/Search/ViewStateToSearchRequestTransformer.php',
    'Search\Search\SearchSimpleService'                       => __DIR__ . '/src/Search/Search/SearchSimpleService.php',
    'Search\AutoSuggester'                                    => __DIR__ . '/src/Search/AutoSuggester.php',
    'Search\QueryCleaner'                                     => __DIR__ . '/src/Search/QueryCleaner.php',
    'Search\Request'                                          => __DIR__ . '/src/Search/Request.php',
    'Search\RequestHandler'                                   => __DIR__ . '/src/Search/RequestHandler.php',
    'Search\SearchSource'                                     => __DIR__ . '/src/Search/SearchSource.php',
    'Search\Util'                                             => __DIR__ . '/src/Search/Util.php',
    'Search\QueueWorker'                                      => __DIR__ . '/src/Search/QueueWorker.php',
    'Search\AbstractDocumentStorer'                           => __DIR__ . '/src/Search/AbstractDocumentStorer.php',
    'Search\DocumentStorer'                                   => __DIR__ . '/src/Search/DocumentStorer.php',
    'Search\TermRecognizer'                                   => __DIR__ . '/src/Search/TermRecognizer.php',
    'Search\Module'                                           => __DIR__ . '/Module.php',
);

从相关的 Module.php 中提取:

public function getAutoloaderConfig() {
    return [
        'Zend\Loader\ClassMapAutoloader' => [
            __DIR__ . '/autoload_classmap.php'
        ],
        'Zend\Loader\StandardAutoloader' => [
            'namespaces' => [
                __NAMESPACE__ => __DIR__ . '/src/' . str_replace('\\', '/', __NAMESPACE__)
            ]
        ]
    ];
}

我已经检查过 Autoloader 使用了类映射。

编辑添加信息:

【问题讨论】:

  • 慢了多少?此外,xdebug 分析用于调试性能问题,不要用它来衡量性能,因为它会增加大量开销并可能会扭曲您的结果。
  • Xdubug 和 webgrind 让网站变得更慢,并且应该只在开发中使用。向我们展示您的 classmap_autoload.php 和配置
  • @stanimir: 当然我只在开发中使用 xdbug ;-) 对不起这个误解
  • @tim:我确实使用了 xdebug,因为我确实看到我没有获得任何性能 => 所以我决定使用 xdebug 进行分析以检查更改前后是否存在差异,我主要使用此过程检查更改是否会带来更好的性能
  • @Gizzmo Module.php 有多大?

标签: php zend-framework2 autoloader


【解决方案1】:

抱歉回复晚了。现在您的应用程序加载半秒 - 准确地说是 0.6 秒。所以我的自动装载机正在做他的工作。您的查询也执行得很快。我还可以想到另外两种方法来加快您的应用程序的速度。

  • 第一种方式 - 使用模板映射

找到您的 templatemap_generator.php 文件。它应该在您的vendor/zendframework/zendframework/bin 文件夹中。导航到您的模块文件夹,例如Application 文件夹所在的src, view, config 目录。打开终端并输入 php ../../vendor/zendframework/zendframework/bin/templatemap_generator.php ZF 将在您的模块目录中创建一个模板映射。现在要使用这个模板,只需修改你的 module.config.php 文件。文件结构与 clasmap_autoloader.php 中的类似

return array(
// Telling where the views are
'view_manager' => array(
    'display_not_found_reason' => true,
    'display_exceptions'       => true,
    'doctype'                  => 'HTML5',
    'not_found_template'       => 'error/404',
    'exception_template'       => 'error/index',
    'template_map' => include __DIR__ . '/../template_map.php', // <-- add this line. You can remove `template_path_stack`
),

在您的控制器中为每个操作添加一个视图模板。 公共索引操作() { $view = 新的 ViewModel(); $view->setTemplate("应用程序/索引/索引"); 返回$视图; }

  • 第二种方式 - 在生产环境中使用模块缓存。

假设您的 .htaccess - SetEnv APPLICATION_ENV "development" 中有这一行

在你的public/index.php 文件中,如果你没有做过类似的事情,添加这个:

/**
 * Set global ENV. Used for debugging
 */
if (isset($_SERVER['APPLICATION_ENV']) && $_SERVER["APPLICATION_ENV"] === 'development') {
    define("APP_ENV", 'development');
} else {
    define("APP_ENV", "production");
}

这将确保您在应用程序中拥有一个全局环境,该环境表明调试是打开还是关闭,它可以帮助您避免 DRY 代码。 现在从你的根文件夹打开config/application.config.php

<?php

$modules = [];

if (APP_ENV === 'development') {
    $modules[] = 'ZendDeveloperTools';
    $modules[] = 'BjyProfiler';
    $modules[] = 'SanSessionToolbar';
}

$modules[] = 'Application';
$modules[] = 'Admin';

return [
    // This should be an array of module namespaces used in the application.
    'modules' => $modules,

    // These are various options for the listeners attached to the ModuleManager
    'module_listener_options' => [
        // This should be an array of paths in which modules reside.
        // If a string key is provided, the listener will consider that a module
        // namespace, the value of that key the specific path to that module's
        // Module class.
        'module_paths' => [
            './module',
            './vendor',
        ],

        // An array of paths from which to glob configuration files after
        // modules are loaded. These effectively override configuration
        // provided by modules themselves. Paths may use GLOB_BRACE notation.
        'config_glob_paths' => [
            'config/autoload/{{,*.}global,{,*.}local}.php',
        ],

        // Whether or not to enable a configuration cache.
        // If enabled, the merged configuration will be cached and used in
        // subsequent requests.
        'config_cache_enabled' => (APP_ENV === 'production'),

        // The key used to create the configuration cache file name.
        'config_cache_key' => md5('app_config'),

        // Whether or not to enable a module class map cache.
        // If enabled, creates a module class map cache which will be used
        // by in future requests, to reduce the autoloading process.
        'module_map_cache_enabled' => (APP_ENV === 'production'),

        // The key used to create the class map cache file name.
        'module_map_cache_key' => md5('module_map'),
        // The path in which to cache merged configuration.
        'cache_dir' => dirname(__DIR__)."/data/cache",

        // Whether or not to enable modules dependency checking.
        // Enabled by default, prevents usage of modules that depend on other modules
        // that weren't loaded.
        'check_dependencies' => (APP_ENV !== 'production'),
    ],

    // Used to create an own service manager. May contain one or more child arrays.
    //'service_listener_options' => [
    //     [
    //         'service_manager' => $stringServiceManagerName,
    //         'config_key'      => $stringConfigKey,
    //         'interface'       => $stringOptionalInterface,
    //         'method'          => $stringRequiredMethodName,
    //     ],
    // )

   // Initial configuration with which to seed the ServiceManager.
   // Should be compatible with Zend\ServiceManager\Config.
   // 'service_manager' => [],
];

config_cache_* 将在您的应用投入生产时激活并缓存您的路由配置。您的所有模块路由都将被缓存。此外,如果网站处于生产状态,则不会加载调试模块。 你可以用任何你想要的替换md5('app_config')

【讨论】:

  • 迟到的答案没问题!无论如何,谢谢你的答案。 TemplateMap 并没有以任何方式提高性能,但是第二个缓存配置确实提高了性能。所以谢谢你。
  • 如果你接受我的回答会很好。 :) 另外,从上面的图片中,我看到你的 I/O 使用了大约 30mb 的内存,所以你必须深入挖掘你的 php 代码并改进它。此外,如果您使用 php 5.5+,我建议您升级到 zend 2.5.1。
  • 所以你的回答对我有帮助,但为什么类映射的自动加载没有提高性能仍然未知。我会等待一段时间,看看是否有人可以给我另一个关于自动加载的提示。之后我将您的分析器标记为已接受,因为您真的试图帮助我:-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-12
  • 1970-01-01
  • 2012-10-02
  • 1970-01-01
  • 1970-01-01
  • 2017-03-07
  • 1970-01-01
相关资源
最近更新 更多