PHP项目Symfony stopwatch性能

wen PHP项目 2

本文目录导读:

PHP项目Symfony stopwatch性能

  1. 基本使用
  2. 高级特性
  3. 最佳实践
  4. 配置优化
  5. 性能分析和可视化
  6. 注意事项

在Symfony项目中,Stopwatch组件是一个非常强大的性能分析工具,我来详细说明它的使用方法和最佳实践。

基本使用

自动注入使用

use Symfony\Component\Stopwatch\Stopwatch;
use Symfony\Component\Stopwatch\StopwatchEvent;
class ProductService
{
    public function __construct(
        private Stopwatch $stopwatch
    ) {}
    public function processProducts(): void
    {
        // 开始计时
        $this->stopwatch->start('product_processing');
        // 业务逻辑
        $products = $this->fetchProducts();
        $this->processBatch($products);
        $this->saveResults();
        // 停止计时
        $event = $this->stopwatch->stop('product_processing');
        $this->logPerformance($event);
    }
}

分段计时(Lap功能)

class DataPipeline
{
    public function execute(): void
    {
        $stopwatch = new Stopwatch();
        // 主事件
        $stopwatch->openSection();
        $stopwatch->start('pipeline', 'data_processing');
        // 第一阶段
        $stopwatch->lap('pipeline');
        $this->extractData();
        // 第二阶段
        $stopwatch->lap('pipeline');
        $this->transformData();
        // 第三阶段
        $stopwatch->lap('pipeline');
        $this->loadData();
        $event = $stopwatch->stop('pipeline');
        $stopwatch->closeSection('pipeline_section');
    }
}

多层嵌套计时

class ComplexOperation
{
    public function execute(): void
    {
        $stopwatch = new Stopwatch(true); // true表示启用内存分析
        // 外层计时
        $stopwatch->start('main_operation');
            // 内层计时1
            $stopwatch->start('subtask_1');
            $this->doTaskOne();
            $stopwatch->stop('subtask_1');
            // 内层计时2
            $stopwatch->start('subtask_2');
            $this->doTaskTwo();
            $stopwatch->stop('subtask_2');
        $event = $stopwatch->stop('main_operation');
        // 分析结果
        foreach ($event->getPeriods() as $period) {
            printf("Duration: %.2f ms\n", $period->getDuration());
        }
    }
}

高级特性

事件分析

class PerformanceAnalyzer
{
    private array $events = [];
    public function analyzeEvent(StopwatchEvent $event): array
    {
        return [
            'name' => $event->getName(),
            'category' => $event->getCategory(),
            'origin' => $event->getOrigin(),
            'start_time' => $event->getStartTime(),
            'end_time' => $event->getEndTime(),
            'duration' => $event->getDuration(),
            'memory' => $event->getMemory(),
            // 详细分段信息
            'periods' => array_map(function($period) {
                return [
                    'start' => $period->getStartTime(),
                    'end' => $period->getEndTime(),
                    'duration' => $period->getDuration(),
                    'memory' => $period->getMemory()
                ];
            }, $event->getPeriods())
        ];
    }
}

自定义分类

class DatabasePerformance
{
    public function trackQueries(): void
    {
        $stopwatch = new Stopwatch();
        // 使用分类组织事件
        $stopwatch->start('query_1', 'mysql');
        $this->executeQuery1();
        $stopwatch->stop('query_1');
        $stopwatch->start('query_2', 'mysql');
        $this->executeQuery2();
        $stopwatch->stop('query_2');
        $stopwatch->start('cache_lookup', 'redis');
        $this->checkCache();
        $stopwatch->stop('cache_lookup');
        // 按分类获取结果
        $mysqlEvents = $stopwatch->getSectionEvents('__root__');
    }
}

最佳实践

日志记录集成

class PerformanceLogger
{
    public function __construct(
        private Stopwatch $stopwatch,
        private LoggerInterface $logger
    ) {}
    public function logPerformance(string $eventName): void
    {
        if ($this->stopwatch->isStarted($eventName)) {
            $event = $this->stopwatch->stop($eventName);
            $duration = $event->getDuration();
            $memory = $event->getMemory() / 1024 / 1024; // MB
            // 记录慢操作
            if ($duration > 1000) { // 超过1秒
                $this->logger->warning("Slow operation detected", [
                    'event' => $eventName,
                    'duration_ms' => $duration,
                    'memory_mb' => round($memory, 2),
                    'category' => $event->getCategory()
                ]);
            }
            // 记录所有操作
            $this->logger->info("Performance metrics", [
                'event' => $eventName,
                'duration_ms' => $duration,
                'memory_mb' => round($memory, 2)
            ]);
        }
    }
}

Profiler集成

#[AsEventListener]
class PerformanceListener
{
    public function __construct(
        private Stopwatch $stopwatch,
        private Profiler $profiler
    ) {}
    public function onKernelResponse(ResponseEvent $event): void
    {
        // 收集本请求的所有性能数据
        $sections = $this->stopwatch->getSectionEvents('__root__');
        foreach ($sections as $name => $sectionEvent) {
            $profilerData = new PerformanceDataCollector();
            $profilerData->addEvent($name, [
                'duration' => $sectionEvent->getDuration(),
                'memory' => $sectionEvent->getMemory()
            ]);
            $this->profiler->add($profilerData);
        }
    }
}

配置优化

条件启用

// config/packages/framework.yaml
framework:
    profiler:
        only_exceptions: false
        collect_serializer_data: true
// 服务配置
services:
    App\Service\PerformanceMonitor:
        arguments:
            $enabled: '%kernel.debug%'
class PerformanceMonitor
{
    private bool $enabled;
    public function __construct(
        private ?Stopwatch $stopwatch,
        bool $enabled = false
    ) {
        $this->enabled = $enabled && $stopwatch !== null;
    }
    public function start(string $name): void
    {
        if ($this->enabled) {
            $this->stopwatch->start($name);
        }
    }
    public function stop(string $name): ?StopwatchEvent
    {
        if ($this->enabled) {
            return $this->stopwatch->stop($name);
        }
        return null;
    }
}

性能分析和可视化

Web Profiler集成

class CustomCollector extends DataCollector
{
    public function __construct(
        private Stopwatch $stopwatch
    ) {}
    public function collect(Request $request, Response $response, ?Throwable $exception = null): void
    {
        $sections = $this->stopwatch->getSectionEvents('__root__');
        $this->data = [
            'total_time' => $this->calculateTotalTime($sections),
            'events' => $this->formatEvents($sections),
            'memory_peak' => memory_get_peak_usage(true)
        ];
    }
    public function getTemplate(): string
    {
        return '@CustomProfiler/performance.html.twig';
    }
}

注意事项

  1. 性能开销:Stopwatch本身有轻微性能开销,生产环境建议禁用
  2. 内存使用:大量计时事件会消耗内存,注意清理
  3. 并发安全:Stopwatch不是线程安全的,在多线程环境下需注意
  4. 嵌套限制:避免过多嵌套层级,建议不超过3层
  5. 命名规范:使用有意义的命名,便于分析

这种方式可以帮助你精确定位性能瓶颈,优化应用性能。

抱歉,评论功能暂时关闭!