2014-11-01 1 views
2

Oboe.js, MongoDB 및 Express.js를 사용하여 HTTP를 통해 JSON 스트리밍을 실험하고 있습니다.Oboe.js, MongoDB 및 Express.js로 JSON 스트리밍

점은 Express.jsMongoDB에서 쿼리 (Node.js를의 MongoDB를 기본 드라이브), 파이프를 (자바 스크립트 배열)을 수행하고 Oboe.js와 브라우저에서 구문 분석하는 것입니다.

내가 수행 한 벤치 마크는 MongoDB 쿼리 서버 측과 클라이언트 측 JSON 구문 분석에서 모두 과 을 비교했습니다.

다음은 두 가지 벤치 마크의 소스 코드입니다. first number1000 queries10 million documents collection100 items (페이지 매김)의 밀리 초 수이고 괄호 사이의 second 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

"왜 오보에인가?"끝에 오보에 박사의 의견이 있습니다. 섹션 :

순수 Javascript 파서이므로 Oboe.js는 JSON.parse보다 많은 CPU 시간을 필요로합니다. Oboe.js는 매우 빠르게로드되는 작은 메시지에 대해서는 약간 느리게 작동하지만, 대부분의 실제 사례에서는 I/O를 사용하여 CPU 시간을 효과적으로 최적화합니다. SAX 파서는 파스 트리를 구성하지 않기 때문에 Oboe의 패턴 기반 파싱 모델보다 적은 메모리를 필요로합니다. Oboe.js vs SAX vs DOM을 참조하십시오. 의심 스럽다면 벤치 마크에서 모바일을 포함한 실제 인터넷을 사용하는 것을 잊지 말고 지각 성능에 대해 생각해보십시오.