MINERVA/C_CPP 2013. 7. 1. 01:15

프러덕트에 적절한 라이브러리 찾다가, 참신한(?) 자료가 내용을 퍼왔습니다.

 

C++에서 Json을 사용할 일이 생기면서 C++에서 사용 가능한 Json Parser를 조사해 봤습니다.

조사결과 다음과 같은 파서가 존재했으며 간단히 특징을 기술해 보고 테스트 결과를 공유하고자 합니다.

 

조사 대상

라이브러리명 언어 기타
jsoncpp (강추) C++ 큰 무리 없이 사용 가능
jansson C

오래되고 안정적임.

단 C 언어라 코딩하기 귀찮음.

단, C언어로 개발해야 한다면 jansson을 쓰는 것이 제일 좋음.

json spirit C++ Boost Spirit library 사용. header only로 설치가 된다던데, 설치 포기.
MongoDB의 json parser C++

mongodb C++ driver에 내장됨. Mongo::fromjson()

mongodb C++ driver에 있으므로 따로 설치할 필요가 없으나, 사용하기는 좀 어려웠음.

UniversalContainer C++ 원래 목적은 PHP 등 스크립트 언어의 자료 구조를 지원하는 용도이나, json으로 encode, decode 가능.
설치 후 하는데 고생을 좀 했는데, 테스트 시 seg. fault가 나서 테스트 포기

 

각 라이브러리별 특징을 조사하면 다음과 같습니다.

 

jsoncpp

  • http://jsoncpp.sourceforge.net/
  • 큰 단점없이 사용 가능.
  • 단, library 빌드 시 -O2 가 안 켜져 있어서 직접 켜줘야 속도가 빠름. 안 그러면 PHP보다 느림.
    • library 소스에서 SConstruct 파일을 열어서 CCFLAGS = "-Wall"에 -O2를 추가하거나 scons로 --opt=-O2 주기.
  • key 순서가 알파벳 순서로 바뀌어 출력됨.
    {
        "k2":"xxx",
        "k1":"yyy"
      }

    의 문서 경우, json 문서를 탐색할 때 항상 k1이 먼저 접근됨.

  • key 순서 문제의 경우, http://sourceforge.net/tracker/?func=detail&atid=758829&aid=3014601&group_id=144446 를 참고하여 소스를 직접 바꾸면 된다고 하는데 아직 실험적인 방식이라 시도해 보진 못함.
  • UTF-8 문서를 읽는데 문제는 없으나, 출력 시 utf8 문자를 \uxxxx 형태로 출력하는 것은 안 됨. (읽을 때는 가능)

 

 

 

jansson

  • http://www.digip.org/jansson/
  • 만든지 오래되고 사용하는 곳도 많은 듯.
  • 단, C 언어라서 코딩하기가 귀찮음.
  • C언어로 개발할 때는 jansson을 사용하는게 제일 좋을 듯.
  • utf8 fully support
  • json object간에 reference count를 수동으로 기록할 수 있고, 메모리 관리를 개발자가 직접할 수 있음.
  • 그러나 이를 관리하기 위한 코딩이 좀 수고스러울 듯.

json spirit

  • http://www.codeproject.com/KB/recipes/JSON_Spirit.aspx
  • Boost Spirit library를 이용하여 만든 JSON Parser
  • header only로 설치 가능하다고 함.
  • utf8 지원
  • 본인은 library 설치가 잘 안 되고 특별한 장점을 찾기 못해서 더 이상 조사 안 함.

MongoDB의 JSON Parser

  • http://api.mongodb.org/cplusplus/2.0.2/namespacemongo.html#a4f542be0d0f9bad2d8cb32c3436026c2
  • mongodb C++ driver를 다운 받으면, Mongo::fromjson() method.
  • mongodb로 프로젝트를 하는 경우, BSONObj를 다룰 줄 알아야 하므로 json parser로 적당할 수도.
  • 단, 64MB 이상의 경우 parsing 하다가 에러 발생.
    • mongo/bson/util/builder.h 파일을 열어서 BSONObjMaxUserSize, BufferMaxSize의 값을 늘리면 해결 가능함.
  • json 파싱 시간은 느리지만, 메모리 사용량은 다른 것보다 적음. (Bson 형태이므로 압축 효과가 있어서 그럴 듯??)
  • JSON 문서가 항상 object로 시작하고 key가 있어야 함. 이건 좀 불편함.
    [{...}] <= object로 시작하지 않아서 안 됨.
      {"temp":[{...}]} 로 변환해야 함.
  • key에 _id가 항상 삽입됨....

UniversalContainer

  • http://greatpanic.com/progdocs/libuc.html
  • 원래 목적은 자료 구조를 PHP, Perl 처럼 쉽게 접근하기 위한 목적임.
  • 자료 구조를 JSON으로 serialize, de-serialize 가능함.
  • FlexLexer.h 파일 문제 때문에 컴파일이 안 되는데 인터넷 찾으면 설치는 가능함.
  • 어렵사리 설치를 했으나, 테스트 해 보면 seg. fault가 많이 발생.
  • 더 이상 테스트 포기
  • 복잡한 자료구조를 담고 사용하는데 편리해 보였는데 테스트 조차 못해서 아쉬움이 큼.
  • 그런데 jsoncpp로 복잡한 자료 구조를 담고 사용하는데 편해서 다행임.

성능 테스트

평가 결과는 각자 환경마다 다를 수 있으니 너무 맹신하진 마세요.

평가 대상

총 5개의 Library 중, 테스트 가능한 다음의 2개 + PHP가 테스트 대상임.

  • jsoncpp
  • janson
  • Mongo::fromjson
  • PHP

평가 환경

  • 입력 파일
    • 파일 사이즈 : 250MB
    • 2차원 array 형.
      [
        {....} <= depth 확장 없음. 총 190만개의 element가 있음.
        ...
        ...
        {....}
      ]
  • 평가 항목
    • parsing 시간
    • parsing 시 메모리 사용량
    • 탐색 시간 (각 element의 특정 key를 출력)

성능 평가 결과

구분 jsoncpp jansson PHP Mongo::fromjson
parsing 시간 10초 13초 10초 24초
메모리 사용량 1.4GB 1.3GB 2.5GB 800MB
탐색 시간 13.7초 13.8초 13.4초 N/A

결과에 대한 소고

 

posted by choiwonwoo

댓글을 달아 주세요