1. 개발 편의성은 좋다.
JsonCPP의 개발 편의성은 좋은 편이다. 일단 API 메뉴얼 자체가 훌륭해서 인터넷의 다른 자료를 볼 필요가 없다. operator가 잘 적용되어 있어서 코딩량 및 가독성도 좋다.
2. 문자열을 hash 구조가 아니라 red/black tree 구조에 저장된다.
Value a = Value(objectValue);
a["foo"] = "bar";
여기서 associative array를 위한 자료 구조는 hash가 아니다. stl::hash_map 구조 같은 것이 아니라 red/black tree라고 한다. 팀에서 JsonCPP의 문자열 key를 위한 자료 구조를 stl::hash_map으로 변경해 보았는데, 성능이 original JsonCPP보다 빠르게 나왔다.
물론 남의 프로젝트를 마음대로 고쳐서 썼다가 무슨 문제가 발생할지 몰라서 hash_map을 도입하진 못했지만 말이다…
red/black tree가 뭔진 잘 모르겠지만 stl::hash_map을 지원해 주면 좋겠다.
3. JsonCPP를 쓰지 말아야 할 곳에도 JsonCPP를 남발하게 된다.
JsonCPP를 사용하면 PHP 같은 스크립트 개발하듯이 복잡한 array나 hash 구조를 많이 쓰게 된다.
인물 객체를 위한 person Data 구조가 필요하고 age와 name을 저장해야 한다고 가정하자.
class를 이용하는 경우
class person
{
public:
void set_age(int age);
void set_name(string name);
unsigned int get_age();
string get_name();
private:
unsigned int age;
string name;
};
...
person me;
me.set_age(10);
me.set_name("kim");
// 디버깅 용으로 person 객체를 출력해야 하는 경우
// C++ class 마다 출력 함수를 만들어 줘야 함.
JsonCPP를 이용하는 경우
Value me = Value(objectValue);
me["age"] = 10;
me["name"] = "kim";
// 디버깅 용으로 객체 내부를 출력하고 싶으면 그냥 cout으로 출력 가능
cout << me;
그냥 눈으로 봐도 JsonCPP를 사용하는 것이 편한다. 그런데 너무 편하다는 것이 문제가 된다.
person 객체의 name을 first_name으로 변경하고 싶은 경우, person을 class로 define했었다면 실수로 name으로 남겨놓더라도 compile time에 detect가 가능하지만, JsonCPP를 사용한 경우 “name”을 그냥 썼더라도 detect가 되지 않음으로서 이는 버그로 남게 된다.
물론 똑똑한 개발자였다면 “name”을 상수로 만들어서 사용했겠지만, 개발자도 사람이라 항상 실수하게 마련이다.
4. 결론
JsonCPP가 나쁜 선택은 아니다. 올해 1월에 다시 조사했을 때에는 rapidjson이 괜찮아보였는데 실제 프로젝트에 써보진 않아서 본인도 뭐라 말하긴 어렵다. (rapidjson 써보신 분 계시면 평가 좀 부탁드립니다.)
JsonCPP를 쓰다보면 너무 편한 나머지 JsonCPP를 남발하게 되는데 간단한 프로그램이면 상관없지만, 복잡한 프로젝트일 수록 그냥 Json 파싱 용도로만 사용하시는 것이 좋겠습니다~