2

Oboe.js、MongoDB、および Express.js を使用して、HTTP を介した JSON ストリーミングを試しています。

ポイントは、MongoDB(Node.js の mongodb ネイティブ ドライブ) でクエリを実行し、それを (JavaScript 配列) にパイプしてExpress.js、ブラウザーでOboe.js.

私が行ったベンチマークは、MongoDB クエリ サーバー側とクライアント側での JSON 解析の両方でstreaming比較しました。blocking

2 つのベンチマークのソース コードを次に示します。はof (ページネーション)のfirst numberミリ秒数で、括弧の間は、MongoDB 結果配列の最初の項目が解析されるまでのミリ秒数を表します。1000 queries100 items10 million documents collectionsecond number

サーバー側のストリーミング ベンチマーク:

// Oboe.js - 20238 (16.887)
// Native - 16703 (16.69)

collection
.find()
.skip(+req.query.offset)
.limit(+req.query.limit)
.stream()
.pipe(JSONStream.stringify())
.pipe(res);

サーバー側のブロッキング ベンチマーク:

// Oboe.js - 17418 (14.267)
// Native - 13706 (13.698)

collection
.find()
.skip(+req.query.offset)
.limit(+req.query.limit)
.toArray(function (e, docs) {
    res.json(docs);
});

これらの結果には本当に驚かされます。

  1. Streamingblocking毎回よりも速くなります。
  2. Oboe.jsJSON.parseネイティブメソッドと比較して、JSON 配列全体を解析する方が高速です。
  3. Oboe.jsJSON.parseネイティブメソッドと比較して、配列の最初の要素を解析する方が高速です。

誰か説明がありますか?私は何を間違っていますか?

2 つのクライアント側ベンチマークのソース コードもここにあります。

クライアント側のストリーミング ベンチマーク:

var limit = 100;
var max = 1000;

var oboeFirstTimes = [];
var oboeStart = Date.now();

function paginate (i, offset, limit) {
    if (i === max) {
        console.log('> OBOE.js time:', (Date.now() - oboeStart));
        console.log('> OBOE.js avg. first time:', (
            oboeFirstTimes.reduce(function (total, time) {
                return total + time;
            }, 0) / max
        ));
        return true;
    }

    var parseStart = Date.now();
    var first = true;
    oboe('/api/spdy-stream?offset=' + offset + '&limit=' + limit)
    .node('![*]', function () {
        if (first) {
            first = false;
            oboeFirstTimes.push(Date.now() - parseStart);
        }
    })
    .done(function () {
        paginate(i + 1, offset + limit, limit);
    });
}

paginate(0, 0, limit);

クライアント側のブロッキング ベンチマーク:

var limit = 100;
var max = 1000;

var nativeFirstTimes = [];
var nativeStart = Date.now();

function paginate (i, offset, limit) {
    if (i === max) {
        console.log('> NATIVE time:', (Date.now() - nativeStart));
        console.log('> NATIVE avg. first time:', (
            nativeFirstTimes.reduce(function (total, time) {
                return total + time;
            }, 0) / max
        ));
        return true;
    }

    var parseStart = Date.now();
    var first = true;

    var req = new XMLHttpRequest();
    req.open('GET', '/api/spdy-stream?offset=' + offset + '&limit=' + limit, true);

    req.onload = function () {
        var json = JSON.parse(req.responseText);
        json.forEach(function () {
            if (first) {
                first = false;
                nativeFirstTimes.push(Date.now() - parseStart);
            }
        });
        paginate(i + 1, offset + limit, limit);
    };

    req.send();
}

paginate(0, 0, limit);

前もって感謝します !

4

1 に答える 1

1

これらのコメントは、「Why Oboe?」の最後にある Oboe doc で見つけました。セクション:

Oboe.js は純粋な Javascript パーサーであるため、JSON.parse よりも多くの CPU 時間を必要とします。Oboe.js は、非常に高速にロードされる小さなメッセージの場合、動作がわずかに遅くなりますが、実際のほとんどのケースでは、I/O を使用すると、CPU 時間を最適化するより効果的です。SAX パーサーは、解析ツリーを構築しないため、Oboe のパターンベースの解析モデルよりも必要なメモリが少なくて済みます。Oboe.js と SAX と DOM を参照してください。疑わしい場合は、ベンチマークを行いますが、モバイルを含む実際のインターネットを使用することを忘れずに、知覚パフォーマンスについて考えてください。

于 2015-09-26T21:54:43.303 に答える