2014-11-01 93 views
2

我正在嘗試通過HTTP使用Oboe.js,MongoDB和Express.js進行JSON流式傳輸。使用Oboe.js,MongoDB和Express.js進行JSON流式傳輸

關鍵是要做好MongoDB查詢(Node.js的的MongoDB的本地驅動器),管它(一個JavaScript數組)Express.jsOboe.js解析它在瀏覽器中。

我在兩個MongoDB查詢服務器端和客戶端的JSON解析中都比較了streamingblocking的基準。

這是兩個基準的源代碼。 first number1000 queries的毫秒數,100 items(分頁)在10 million documents collectionsecond number括號之間,表示在解析MongoDB結果數組中的第一項之前的毫秒數。

的流基準服務器端:

// 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. Streaming每次都會比blocking更快。
  2. Oboe.js與原生JSON.parse方法相比,解析整個JSON數組會更快。
  3. Oboe.js比解析本地JSON.parse方法更快地解析數組中的第一個元素。

有沒有人有解釋? 我在做什麼錯?

以下是兩個客戶端基準測試的源代碼。

流媒體標杆客戶端:

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); 

謝謝!

回答

1

我在Oboe doc的「爲什麼是雙簧管」結尾處發現了這些評論?部分:

因爲它是純粹的JavaScript解析器,所以Oboe.js比JSON.parse需要更多的CPU時間。對於加載非常快的小型消息,Oboe.js稍微慢一點,但對於大多數真實世界中使用I/O的情況,Oboe.js有效地節省了CPU時間。 SAX解析器比Oboe的基於模式的解析模型需要更少的內存,因爲它們不構建解析樹。請參閱Oboe.js與SAX與DOM的比較。 如果有疑問,基準,但不要忘記使用包括手機在內的真實互聯網,並考慮感知性能。