我写了一个端口扫描器,Rust再一次比Go慢,问题出在哪里呢?

💡 原文中文,约5200字,阅读约需13分钟。
📝

内容提要

本文探讨了使用Go和Rust编写TCP端口扫描器的性能差异。Go版本执行时间不到1秒,而Rust版本超过2秒。作者希望了解Rust性能较慢的原因,并尝试将Go代码迁移到Rust中,但在通道实现上遇到问题。此外,在高并发情况下,Rust和Go都无法扫描某些高端口。

🎯

关键要点

  • 本文探讨了使用Go和Rust编写TCP端口扫描器的性能差异。

  • Go版本执行时间不到1秒,而Rust版本超过2秒。

  • 作者希望了解Rust性能较慢的原因,并尝试将Go代码迁移到Rust中。

  • 在通道实现上遇到问题,tokio似乎只有oneshot和mpsc两种通道。

  • Rust版本在高并发情况下无法扫描某些高端口。

  • 作者的测试用例并不完全等价,Rust版本的并发数设定较高时速度更慢。

  • 在Rust中调整并发数到65535时,无法扫描到某些高端口。

  • Go语言如果直接给每个tcp链接起一个go程而不使用worker模式,也无法扫描到这些端口。

🔎

延伸解读

性能差异的原因

文章指出,Go版本的TCP端口扫描器执行时间明显快于Rust版本,主要原因可能与两者的并发处理方式有关。Go使用了简单的goroutine,而Rust在使用tokio时,可能由于通道实现的限制,导致性能下降。理解这些差异有助于开发者在选择语言时做出更明智的决策。

高并发下的限制

在高并发情况下,Rust和Go都无法扫描某些高端口,这提示开发者在设计网络应用时需考虑并发数与端口范围的关系。特别是在Rust中,调整并发数到65535时,无法扫描到某些高端口,可能是由于系统资源限制或网络栈的处理能力。

通道实现的挑战

作者在尝试将Go代码迁移到Rust时,遇到了tokio通道实现的限制,尤其是mpsc通道无法满足需求。这反映出在不同语言间迁移代码时,通道和并发模型的差异可能会导致额外的复杂性,开发者需对此保持警惕。

延伸问答

为什么Rust版本的TCP端口扫描器执行时间超过2秒?

Rust版本的执行时间较长,主要是由于并发数设定较高时速度更慢,以及在高并发情况下无法扫描某些高端口。

Go和Rust在TCP端口扫描器的性能差异是什么?

Go版本执行时间不到1秒,而Rust版本超过2秒,显示出Go在此任务上的性能优势。

在Rust中如何实现TCP端口扫描的并发?

Rust使用tokio库的异步特性,通过buffer_unordered方法控制并发,允许同时处理多个TCP连接。

Rust版本在高并发情况下无法扫描某些高端口的原因是什么?

当并发数调整到65535时,Rust版本无法扫描高端口,可能是由于系统资源限制或TCP连接的管理问题。

在将Go代码迁移到Rust时遇到的主要问题是什么?

主要问题是tokio库的通道实现,特别是mpsc通道无法满足代码迁移的需求,因为Receiver无法被clone。

如何优化Rust版本的TCP端口扫描器以提高性能?

可以尝试调整并发数和超时时间,避免达到某些阈值导致无法扫描高端口,同时优化TCP连接的管理。

🏷️

标签

➡️

继续阅读