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

如何优化9500行量级的JSON与DataTable处理代码?能否免foreach遍历?

代码优化方案与问题解答

关于"无需foreach遍历直接获取所需对象"的问题

allowedItemIds是集合类型的JSON字段,每个元素都需要单独匹配DataTable行并生成输出文本,无法完全跳过遍历——因为必须处理集合中的每一个元素。不过可以通过强类型反序列化直接获取目标对象,同时用更简洁的方式替代显式foreach(比如LINQ),优化整体逻辑。

核心优化措施(针对9500行数据的性能与简洁性)

1. 替换dynamic为强类型反序列化

用强类型模型替代dynamic,既能直接获取所需的allowedItemIds和responseId对象,又能避免动态解析的性能损耗,同时保证类型安全。

// 定义与JSON结构匹配的强类型模型
public class ResponseData
{
    [JsonProperty("allowedItemIds")] // 对应JSON中的字段名
    public List<int> AllowedItemIds { get; set; }
    
    [JsonProperty("responseId")]
    public string ResponseId { get; set; }
}

// 反序列化JSON,直接获取目标对象
var responseData = JsonConvert.DeserializeObject<ResponseData>(response.Content);
var allowedItemIds = responseData.AllowedItemIds;
var responseId = responseData.ResponseId;

2. 优化文件写入逻辑(大幅提升IO性能)

原代码中File.AppendAllText会在每次循环中打开、写入、关闭文件,9500次操作会产生巨大的IO开销。改用批量写入方式:

方式一:StreamWriter批量写入

dt.PrimaryKey = new[] { dt.Columns["number"] };

using (var writer = new StreamWriter(newFileName, append: true))
{
    foreach (var allowedItem in allowedItemIds)
    {
        var drw = dt.Rows.Find(allowedItem);
        if (drw == null) continue; // 避免找不到行时的空引用异常
        
        // 用列名访问DataRow,替代ItemArray索引,提升可读性
        var number = drw["number"]?.ToString();
        var surname = drw["surname"]?.ToString();
        var forename = drw["forename"]?.ToString();
        var emailAddress = drw["emailAddress"]?.ToString();
        
        // 字符串插值替代拼接,代码更简洁
        var clientDetails = $" {number},\"{surname}\",\"{forename}\",\"{emailAddress}\",\"{responseId}\",\"{daytime}\"";
        writer.WriteLine(clientDetails);
    }
}

方式二:LINQ+File.AppendAllLines(更简洁的写法)

用LINQ简化遍历逻辑,File.AppendAllLines会一次性写入所有行:

dt.PrimaryKey = new[] { dt.Columns["number"] };

var outputLines = allowedItemIds
    .Select(itemId => dt.Rows.Find(itemId))
    .Where(row => row != null) // 过滤不存在的行
    .Select(row => $" {row["number"]?.ToString()},\"{row["surname"]?.ToString()}\",\"{row["forename"]?.ToString()}\",\"{row["emailAddress"]?.ToString()}\",\"{responseId}\",\"{daytime}\"");

File.AppendAllLines(newFileName, outputLines);

3. 其他细节优化

  • 移除无用变量:原代码中resp变量未被使用,直接删除。
  • 增加空值判断:添加if (drw == null) continue;处理DataTable中找不到对应ID的情况,避免空引用异常。
  • 用列名访问DataRow:替代ItemArray[index],代码更易维护,后续列顺序变化不会引发错误。

优化后的效果

  • 性能:IO操作从9500次减少到1次,强类型反序列化比dynamic更高效,整体处理速度大幅提升。
  • 简洁性:代码结构清晰,类型安全,可读性和可维护性显著提高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 17:35:23