解决使用 Html Agility Pack 解析网页时并行优化无效的问题

HtmlAgilityPack 是一个 HTML 解析库,用于 .NET 平台。它允许开发者以类似于解析 XML 的方式,轻松地解析和操作 HTML 文档。这个库特别适合处理非标准的 HTML,例如那些格式不正确或包含错误的 HTML 文档。

从原理上说,解析是一个 CPU 密集型操作。在计算资源充裕的情况下,使用多线程并行可以加快处理速度。

以下代码展示了两个场景:

  • 使用一个线程解析 1000 个页面

  • 使用 8 个线程解析 1000 个页面(总量 1000 个,测试机器上的 CPU 有 8 个内核)。

string html = File.ReadAllText("PATH");
//One thread
for (int i = 0; i < 1000; i++)
   new HtmlDocument().LoadHtml(html);
//Several threads
Parallel.For(0, 1000, (int i) => new HtmlDocument().LoadHtml(html));

然而实际的情况是:尽管多线程版本消耗了 2 ~ 3 倍的 CPU,但所花费的时间大致相同。而且 CPU 占用率一直维持在 30% 以下。即便更换了要处理的页面,或者内核数量更多的电脑,情况都差不多。

如何解决

开启更多的线程并不会提升处理的速度,这让我开始怀疑是不是存在锁的问题。遗憾的是没有在源代码中找到 lock ,但是发现了一个 Issues:

https://github.com/zzzprojects/html-agility-pack/issues/191

在使用 Profiler 工具对多线程程序进行分析之后,发现程序可能存在内存瓶颈。根据他的观察,有大约 50% 的 CPU 时间耗费在了内存分配上。

这和使用的 GC 类型有关,向 App.config 增加以下代码可以解决该问题:

<runtime>
    <gcServer enabled="true"/>
    <gcConcurrent enabled="false" />
  </runtime>

适配 .NET 8.0

我的程序是一个使用 .NET 8.0 框架的控制台,增加 App.config 文件之后并没有效果。于是,我找到了微软的官方文档:

https://learn.microsoft.com/zh-cn/dotnet/core/runtime-config/garbage-collector

根据文档所述,可以通过环境变量、runtimeconfig.json 文件或项目文件来指定程序使用 Server 版本。我选择修改项目文件:

<Project Sdk="Microsoft.NET.Sdk">


  <PropertyGroup>
    <ServerGarbageCollection>true</ServerGarbageCollection>
  </PropertyGroup>


</Project>

问题得以解决:处理速度快了不少,CPU 占用维持在了 70% 左右。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
架构的敏捷性是指一个体系结构设计的能力,能够适应不断变化的需求和环境。它强调使用灵活的方法来构建可扩展、易于修改和适应不同场景的系统。 首先,架构的敏捷性可以通过模块化的设计实现。模块化的架构将系统划分为相互独立的组件,使得修改一个组件不会对其他组件产生影响。这样就能够在不改变整体架构的情况下,快速响应变化的需求。 其次,架构的敏捷性还需要具备良好的可扩展性和可配置性。这意味着系统可以根据需要进行扩展,从而满足不断变化的需求。同,系统的各个组件应该具有灵活的配置选项,使得可以快速调整系统的行为和功能。 另外,在架构设计中,还要注重减少耦合性。高度耦合的系统难以修改和扩展,而低耦合的系统则能够更容易地应对变化。通过使用松散耦合的设计模式和技术,可以使各个组件之间的依赖性减少,从而提高架构的敏捷性。 最后,架构的敏捷性也需要支持持续集成和自动化测试。持续集成确保系统的不断演化,并及发现和解决问题,从而提高敏捷性。自动化测试可以快速验证系统的正确性和稳定性,帮助减少错误和风险。 总的来说,架构的敏捷性是根据需求和环境的变化,通过模块化、可扩展性、可配置性、减少耦合性以及持续集成和自动化测试等手段,使系统能够快速适应和响应变化,从而保持灵活和可持续的发展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值