【问题标题】:Why does PHP come out on top over Node.js when I benchmark them on a IO operation?当我在 IO 操作上对 PHP 进行基准测试时,为什么 PHP 比 Node.js 更胜一筹?
【发布时间】:2016-11-17 02:27:43
【问题描述】:

我正在使用 apache 基准测试工具在 PHP 和 Node.js、端口 80 和端口 8000 上分别运行基准测试。下面的节点基准测试命令,在 PHP 上运行测试时交换端口:

ab -n 100 -c 100 http://localhost:8000/

我在程序中所做的只是读取一个 10MB 的文本文件,然后将其发送回客户端。令我惊讶的是,PHP 基准测试需要大约 6 秒,而 Node.js 则需要 13 秒。

这是文本文件:

https://github.com/jamesward/play-load-tests/blob/master/public/10mb.txt

这是每个的代码:

Node.js

var http = require("http");
var fs = require("fs");
var s = http.createServer(function(req, res) {

    res.writeHead(200, {"content-type": "text/plain"});

    fs.readFile("./10mb.txt", "utf8", function(err, data) {

        res.end(data);

    });     


});

s.listen(8000);

PHP

<?php

echo file_get_contents("./10mb.txt");

我在 Node 代码中做错了吗?否则我很困惑,Node 的主要卖点之一是它在 OI 操作中的速度很快。我错过了什么?

【问题讨论】:

  • 这里的版本号将是关键。我假设 PHP 和 Node.js 都是最新版本?
  • 我不认为这个问题会吸引有用的答案,而是会以“好吧,因为 [x] 简直太臭了”的形式吸引了大量的猜测和一些高度自以为是的答案。您可以尝试通过阅读脚本in 来获取有关节点脚本的更多详细信息,看看哪些部分会减慢您的速度。可能是将其加载到变量中并然后将其发送到客户端需要更多时间,而 PHP 会自动优化 no-variable-one-liner?
  • 是 PHP 7 和 Node LTS,6.9.1
  • 先将 php file_get_contents 返回值放入变量中,然后在第二行回显该变量并没有使其变慢。

标签: php node.js http io


【解决方案1】:

PHP 将运行多线程,因此 100 个请求中的一些将是并行的。

Node.js 是单线程但异步的。一般来说,这种权衡是 Node.js 的胜利,因为它将消耗更少的 RAM 并导致更少的上下文切换。但是,在这种情况下,您正在将大量数据 (10mb) 读取到 RAM 中,然后将其发送出去。

node.js 中的内存操作是同步的。因此,虽然文件读取和套接字写入操作都是异步的,但其中有一个巨大的 memcpy 有效地阻塞了解释器。

在 node.js 中处理超大数据的正确方法是使用流:

var s = http.createServer(function(req, res) {
    var readStream = fs.createReadStream("./10mb.txt");

    res.writeHead(200, {"content-type": "text/plain"});

    readStream.pipe(res);
});

【讨论】:

  • 附带说明 - 这也意味着在 RAM 中缓存大数据在 node.js 中会适得其反。将数据缓存为文件并让异步 I/O 处理它会更快。我的经验法则是任何低于 1MB 的东西都可以缓存在内存中。任何更大的东西都应该使用临时文件或数据库。
  • 你是对的!使用流并在每个请求中创建该流,就像您在请求事件的处理程序中那样,使其比 PHP 更快。我将基准测试中的原始 100 个请求提高到 300 个,PHP 在 17 秒内完成,节点在 16 秒内完成。如果我只在请求处理程序之外创建一次读取流,它会以惊人的 400 毫秒处理所有这些请求。必须将单个读取流的最大事件侦听器数量从 10 个增加到 1000 个(1000 个有效,可能不需要 1000 个侦听器)这是一种好的做法吗?
猜你喜欢
  • 2017-09-18
  • 1970-01-01
  • 2012-02-10
  • 2012-10-29
  • 2011-08-17
  • 1970-01-01
  • 2010-12-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多