You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

LINQ查询优化咨询:按版本分组统计Proxy与非Proxy数据

Nice catch on the performance issue with your original LINQ query! Redundant iterations over the same data can really add up when dealing with large datasets, so let's look at how we can optimize this to be both efficient and clean.

First, let's break down the problem with your original implementation:

Your original code groups servers by Version.Major, but then runs two separate Where + Sum operations per group (one for non-proxy servers, one for proxies). This means each group gets iterated twice—doubling the work for large datasets.

Your self-improved version fixes this by first grouping on both Version.Major and IsProxy, calculating sums in a single pass over the raw data. That's a great step forward, but we can streamline it further to eliminate intermediate objects and extra grouping steps.

Option 1: Single-pass group processing with foreach (most readable & performant)

This approach iterates each group exactly once, calculating both game and proxy stats in a single loop. No redundant LINQ operations, minimal overhead:

var result = servers.GroupBy(x => x.Version.Major)
    .ToDictionary(
        group => $"{group.Key}.0.0",
        group =>
        {
            var gameStats = new Statistics();
            var proxyStats = new Statistics();

            foreach (var server in group)
            {
                if (server.IsProxy)
                {
                    proxyStats.IntData1 += server.IntData1;
                    proxyStats.IntData2 += server.IntData2;
                }
                else
                {
                    gameStats.IntData1 += server.IntData1;
                    gameStats.IntData2 += server.IntData2;
                }
            }

            return new StatisticsModel
            {
                Game = gameStats,
                Proxy = proxyStats
            };
        });

Option 2: Pure LINQ with Aggregate

If you prefer a fully declarative LINQ approach without explicit loops, Aggregate lets you accumulate stats in a single pass over each group:

var result = servers.GroupBy(x => x.Version.Major)
    .ToDictionary(
        group => $"{group.Key}.0.0",
        group => group.Aggregate(
            new StatisticsModel { Game = new Statistics(), Proxy = new Statistics() },
            (acc, server) =>
            {
                if (server.IsProxy)
                {
                    acc.Proxy.IntData1 += server.IntData1;
                    acc.Proxy.IntData2 += server.IntData2;
                }
                else
                {
                    acc.Game.IntData1 += server.IntData1;
                    acc.Game.IntData2 += server.IntData2;
                }
                return acc;
            }));

Why these are better

  • Both options process each group once instead of twice, cutting down on unnecessary work.
  • They eliminate the intermediate anonymous objects and second grouping step from your improved code, reducing memory overhead and making the logic more direct.
  • The foreach version is slightly more performant (avoids delegate invocation overhead from Aggregate) and easier to debug, while the Aggregate version stays fully within LINQ syntax.

内容的提问来源于stack exchange,提问作者Андрей Рутковский

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 07:24:22