Bun JavaScript 引擎的主要作者 Jarred Sumner 几天前在 X 上评论说,由于线程争用,在 macOS 上打开许多文件可能会很慢:“你的 5,000 美元的计算机一次只能打开 1 个文件”。
我很好奇,决定测试一下。我编写了一个小型 C++ 程序,可以打开 1000 个文件。文件立即打开和关闭。但是,有 1000 个不同的(空)文件。这是一个简单的测试:没有写入并且文件不会长时间保持打开状态。
我使用 1 个线程、2 个线程、8 个线程或 16 个线程。线程平均分配工作:例如,使用两个线程,每个线程打开 500 个文件。
为了让事情变得有趣,让我们添加一个“线程池”:我在基准测试开始之前创建并启动所有线程。然后我将所有任务(打开文件 X)添加到线程池中。这应该会更慢,但对于工程师解决此类问题的方式可能更现实。
我将每个测试运行 10 次并保留中位数。这些措施存在一些不稳定,我尝试报告有代表性的数字。我的代码位于 GitHub 上:我邀请您在您的系统上运行它。
首先让我们看一下我的 Apple M2 笔记本电脑上的结果(它有 8 个核心,4 个性能 + 4 个效率)。不幸的是,我现在没有更强大的苹果电脑可供使用。
我报告总时间。
线程 | 常规的 | 带线程池 |
---|---|---|
1 线程 | 100毫秒 | 140毫秒 |
2 线程 | 75毫秒 | 100毫秒 |
4 线程 | 90毫秒 | 95毫秒 |
8 线程 | 240毫秒 | 250毫秒 |
16 线程 | 250毫秒 | 270 毫秒 |
让我们在 Linux 下的 64 核大型 x64 服务器上进行测试。尽管它是一台更大的机器,但它的每核心性能总体上比 Apple MacBook 差(内存较慢、时钟较慢、每周期指令较少)。
线程 | 常规的 | 带线程池 |
---|---|---|
1 线程 | 34毫秒 | 55毫秒 |
2 线程 | 25毫秒 | 36毫秒 |
4 线程 | 31毫秒 | 27 毫秒 |
8 线程 | 36毫秒 | 16毫秒 |
16 线程 | 42 毫秒 | 27 毫秒 |
macOS 系统拥有更快的磁盘、更快的内存和更快的内核。然而,根据此测试,在 macOS 下打开文件显然要慢得多。
我发现有趣的是,在这两种情况下,使用两个线程可以最大限度地减少常规情况下的运行时间:额外的线程似乎会减慢速度。
对于大型机器,如果我使用四个或更多线程,线程池可以比常规方法更快。
在我的 MacBook 上,我每秒无法打开超过 12,000 个文件。我的 Linux 服务器每秒可扩展至 40,000 个文件。在某些情况下,打开数千个文件可能会成为一个硬瓶颈。在问题上投入更多线程可能不起作用。
原文: https://lemire.me/blog/2025/03/01/how-fast-can-you-open-1000-files/