libmongoclient의 JSON parser를 쓰다가 Array에 4096 개라는 제한이 있어서 다른 JSON Parser를 찾아봤다.

속도와 편리성 위주로 고르다 보니 picojson, rapidjson, libjson, vjson 이렇게 넷이 선정되었다.

  • 측정 방법: 2만여 JSON 문서를 Parsing 후 2차원 문자열 배열을 stdout으로 출력
  • 측정 기준: 실행 시간 측정
  • 결과
  시간(분:초)  Destructive  Header-only  Writable  Modifiable
 MongoDB  3:02 (Parsing Failed: 2797/20072)  X  X  O  X
 picojson  6:18  X  O  X  X
 libjson  3:50  X  X  O  O
 vjson  1:45  O  X  X  X
 rapidjson(destructive mode)  1:29  Avail  O  O  O
  • 분석: rapidjson과 vjson은 원본을 복사하지 않고 수정해서 파싱하기 때문에 가장 빨랐다.
vjson을 쓸 수도 있겠지만, 다른 프로그램의 MongoDB 모듈을 모두 대체하려면 Write 기능이 필요해서 rapidjson을 최종 선택하였다.
한 프로그램(JSON parse/modify/write)의 MongoDB 모듈을 rapidjson으로 대체 결과
   전체 실행 시간  파싱 소요시간
 MongoDB  1분1초  29초
 rapidjson  33초  7초

파싱 시간 뿐 아니라 write 시간도 단축 되었음(Building new object -> Modifying).

무심코 STL 책을 읽다가 이걸 보고 깜짝 놀랐다.

vector에서 push_back()이나 resize()의 효율이 O(n)인 줄 알고 속도 향상 한답시고 reserve()호출했었는데,

Amortized Constant(상환 상수?) 복잡도라 미리 2n개를 확보 한댄다;;; 괜히 건드렸다;;;

Text Code: http://www.cplusplus.com/reference/vector/vector/reserve/ (push_back을 resize로 바꿔도… 동일)

뱀발> 사전적으로는 ‘(분할) 상환 상수’가 맞을 듯 한데, 어떤 책에서는 ‘양도 상수’로 번역을 한 듯;;;

결과


strA==strA


==> elapsed time : 1.08 sec

strA==strB


==> elapsed time : 1.09 sec

strcmp(szA,szB)


==> elapsed time : 0.12 sec

strcmp(szA,szA)


==> elapsed time : 0.11 sec

strcmp(strA,strB)


==> elapsed time : 0.25 sec

strcmp(strA,strA)


==> elapsed time : 0.25 sec

Source Code



#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <string>
#include “Blib.h”

using namespace std;
#define TEST_SIZE 1<<20
#define ITER 1<<25

void compare()
{
string strBuffer1(TEST_SIZE, ‘a’);
string strBuffer2(TEST_SIZE, ‘b’);

char szBuffer1[TEST_SIZE+1];
memset(szBuffer1 , ‘a’, TEST_SIZE);
szBuffer1[TEST_SIZE]=’\0′;
char szBuffer2[TEST_SIZE+1];
memset(szBuffer2 , ‘b’, TEST_SIZE);
szBuffer2[TEST_SIZE]=’\0′;

Blib::TStopWatch w;
puts(“strA==strA\n”);
for (int i=0;i<ITER;i++)
strBuffer1 == strBuffer2;
w.Print(stderr);

w.Reset();
puts(“strA==strB\n”);
for (int i=0;i<ITER;i++)
strBuffer1 == strBuffer2;
w.Print(stderr);

w.Reset();
puts(“strcmp(szA,szB)\n”);
for (int i=0;i<ITER;i++)
strcmp(szBuffer1, szBuffer2);
w.Print(stderr);

w.Reset();
puts(“strcmp(szA,szA)\n”);
for (int i=0;i<ITER;i++)
strcmp(szBuffer1, szBuffer1);
w.Print(stderr);

w.Reset();
puts(“strcmp(strA,strB)\n”);
for (int i=0;i<ITER;i++)
strcmp(strBuffer1.c_str(), strBuffer2.c_str());
w.Print(stderr);

w.Reset();
puts(“strcmp(strA,strA)\n”);
for (int i=0;i<ITER;i++)
strcmp(strBuffer1.c_str(), strBuffer1.c_str());
w.Print(stderr);
}

main()
{
compare();
}


분석


어이없다;;; string 안에 뭐가 들어있길래 저리 차이가 나누???