我目前正在开发一个 Laravel 应用程序,该应用程序合并来自两个集合的统计信息:postStats(标准集合)和 contentStats(LazyCollection)。我使用的 mergeStats 方法多次迭代每个集合以求和各种指标,这在处理大型数据集时会导致性能问题,对于 1000 个帖子和 1000 个内容,需要大约 10 秒,记录可能比这个大得多.
代码:
private function mergeStats(Collection $postStats, LazyCollection $contentStats, bool $dashboardStats = false): array
{
$startTime = microtime(true);
$keys = [
'reactions_count',
'comments_count',
'sc_shares_count',
'confirmed_regular_shares_count',
'sc_clicks_count',
'unconfirmed_regular_shares_count',
'confirmed_shares_click_count',
];
// Current logic here to merge postStats and contentStats,
$mergedStats = $postStats->concat($contentStats)->reduce(static function ($carry, $stats) use ($keys) {
foreach ($keys as $key) {
$carry[$key] = ($carry[$key] ?? 0) + ($stats[$key] ?? 0);
}
return $carry;
}, array_fill_keys($keys, 0));
$mergedStats['dashboard_stats'] = $dashboardStats;
return CalculateEngagementMetricsAction::run($mergedStats); //based on the merged stats, it does some calculations, This action is not the culprit for performance.
}
为了提高 mergeStats 方法的性能,关键是优化迭代集合和汇总指标的方式。由于您同时使用标准集合和 LazyCollection,因此我们可以利用惰性求值来更有效地处理大型数据集。
解决方案
以下是调整 mergeStats 方法的方法:
use Illuminate\Support\LazyCollection;
private function mergeStats(Collection $postStats, LazyCollection $contentStats, bool $dashboardStats = false): array
{
$keys = [
'reactions_count',
'comments_count',
'sc_shares_count',
'confirmed_regular_shares_count',
'sc_clicks_count',
'unconfirmed_regular_shares_count',
'confirmed_shares_click_count',
];
// Convert postStats to LazyCollection for efficient handling
$postStats = LazyCollection::make(function () use ($postStats) {
foreach ($postStats as $item) {
yield $item;
}
});
// Concatenate and reduce both collections lazily
$mergedStats = $postStats->concat($contentStats)->reduce(static function ($carry, $stats) use ($keys) {
foreach ($keys as $key) {
$carry[$key] = ($carry[$key] ?? 0) + ($stats[$key] ?? 0);
}
return $carry;
}, array_fill_keys($keys, 0));
$mergedStats['dashboard_stats'] = $dashboardStats;
return CalculateEngagementMetricsAction::run($mergedStats);
}
说明:
这种方法应该可以显着提高性能,特别是对于大型数据集。如果您需要进一步说明或帮助,请告诉我!