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 형태로 출력하는 것은 안 됨. (읽을 때는 가능)
- 앞으로 지원할 예정이라고 함.
- http://jsoncpp.sourceforge.net/roadmap.html 여기에 TODO가 정리됨.
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 |
결과에 대한 소고
- PHP가 생각보다 빠름.
- parsing 자체는 C 모듈이 담당하기 때문이겠지...
- 그래도 jsoncpp나 jansson이 더 빠르길 기대했는데 좀 아쉬움..
- jansson이 약간 느린데 jansson library가 -O2 켜진 상황에서 설치된 것인지 확인 못함.
- 만약 O2가 아닌 상태로 설치되어서 O2를 킨다고 하면 좀 더 빨라질 수 있으므로 참고.
- JSON 포맷에 따라 결과가 달라질 수 있으므로 유의.
반응형