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

C# LINQ如何合并两次Select操作为单次以提升执行性能

C# 合并LINQ两次Select操作实现性能优化

场景说明

基于CloudNative.CloudEvents NuGet包处理云原生事件,输入参数为Cosmos DB Trigger传入的IReadOnlyList类型数据,原有实现使用两次连续的Select做投影转换,需要合并为单次执行以降低枚举开销、提升性能。

原有实现代码

核心LINQ转换逻辑

var orderEvents = input
    .Select(_ => new OrderDocument(_.Id, _.ToString()).ToOrderEvent())
    .Select(_ =>
        new CloudEvent()
        {
            Type = _.EventType,
            Subject = _.Subject,
            Source = _.Source,
            Data = _
        });

关联类定义

OrderDocument

public class OrderDocument
{
    public string Id { get; private set; }

    public string Json { get; private set; }

    public OrderDocument(string id, string json)
    {
        Id = id;
        Json = json;
    }

    public OrderEvent ToOrderEvent() => OrderEventHelper.ToOrderEvent(Json);
}

OrderEventHelper 转换方法

public static OrderEvent ToOrderEvent(string json)
{
    ArgumentHelper.ThrowIfNullOrEmpty(json);

    var orderEvent = JsonConvert.DeserializeObject<OrderEvent>(json);
    var eventDefinition = OrderEvents.EventDefinitions.SingleOrDefault(_ => _.EventType == orderEvent.EventType);

    
    return eventDefinition == null
        ? orderEvent
        : new OrderEvent(
            orderEvent.Id,
            orderEvent.Source,
            orderEvent.EventType,
            orderEvent.Subject,
            orderEvent.DataContentType,
            orderEvent.DataSchema,
            orderEvent.Timestamp,
            JsonConvert.DeserializeObject(orderEvent.Payload.ToString(), eventDefinition.PayloadType),
            orderEvent.TraceId);

}

优化方案

两次连续Select会对序列生成两层迭代器,产生额外的枚举开销和中间对象分配,合并时只需要将两次投影的逻辑内联到同一个Select委托中即可,业务逻辑和原有实现完全等价:

var orderEvents = input
    .Select(_ => 
    {
        // 原第一次Select逻辑:生成OrderEvent实例
        var orderEvent = new OrderDocument(_.Id, _.ToString()).ToOrderEvent();
        // 原第二次Select逻辑:映射为CloudEvent实例
        return new CloudEvent()
        {
            Type = orderEvent.EventType,
            Subject = orderEvent.Subject,
            Source = orderEvent.Source,
            Data = orderEvent
        };
    });

额外优化点

观察现有代码可以发现,OrderDocument实例化后仅调用了ToOrderEvent()方法,而该方法内部完全没有使用OrderDocument的Id属性,属于冗余的临时对象分配,可以直接省略,进一步减少GC压力:

var orderEvents = input
    .Select(_ => 
    {
        // 直接调用转换方法,省掉冗余的OrderDocument临时对象
        var orderEvent = OrderEventHelper.ToOrderEvent(_.ToString());
        return new CloudEvent()
        {
            Type = orderEvent.EventType,
            Subject = orderEvent.Subject,
            Source = orderEvent.Source,
            Data = orderEvent
        };
    });

注意:如果后续业务需要使用OrderDocument的Id属性参与转换逻辑,请勿省略OrderDocument的实例化步骤。


内容的提问来源于stack exchange,提问作者Penguen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 10:45:39