LOGIN • JOININ

네트워크 처리부분에서 데이터를 전송하고 받는 I/O 처리와 함께 가장 중요한 기능 중에 하나가 바로 메시지의 내용을 읽어 내고 쓰는 기능일 것입니다.

즉 전송하고자 하는 내용을 선형 버퍼에 차례대로 써넣거나 전송받은 데이터의 내용을 다시 읽어 오는 일명 직렬화를 말하는 것입니다.

이 직렬화 부분은 사용 상의 편의성도 매우 중요하지만 서버에 있어서는 매우 빈번히 사용되기 때문에 성능 역시 무시할 수가 없습니다.


많이 알려진 직렬화 라이브러리인 protobuf와 JSON을 사용한 방법 그리고 CGCII에서 제공하는 C#버전의 CGD.buffer와 C++버전 CGD::buffer의 성능을 비교해 보았습니다.


매우 다양한 형태의 데이터들에 대해 테스트를 할수 있지만 그냥 일반적인 성능을 파악하기 위한 몇가지의 예제를 만들어 테스트 했습니다.


각 테스트는 데이터를 직렬화해서 써넣고 쓴 데이터를 다시 읽어 내는 것을 백만회(1,000,000회) 반복한 시간을 체크했습니다.



1. 테스트 내용


Test1)    '기본적인 데이터' 쓰고 읽기

char형, unsigned char, int16, int32, int64, float, double 등과 같은 가장 기본적인 데이터를 읽고 쓰는 테스트를 했습니다.

CGD::buffer형으로 표현하자면 아래와 같습니다.

// 값쓰기
append<char>(3);
append<unsigned char>(4);
append<int16_t>(4100);
append<uint16_t>(32210);
append<int32_t>(123310);
append<uint32_t>(121234);
append<int64_t>(-1000443);
append<uint64_t>(12233094310);
append<float>(1.0f);
append<double>(2.0);



Test2. '유니코드 문자열' 쓰고 읽기

유니코드형 문자열 8개를 쓰고 읽는 테스트를 했습니다.

L"Please Let test this"
L"이것 좀 테스트하게 해주세요."
L"这件事 试验"
L"これを試ためさせてください"
L"1234567!@#$%%^&}¢‡¥”w¯¥„ÈÉÞ´µ½²ÂÄÂÁ¾¿ÀÁÂ"
L"Please 这件事 試ためさせてください 합시다."
L"Test What ever"
L"1234"



Test 3. int형 배열 (list<int>) 쓰고 읽기

int형 배열 8개를 쓰고 읽는 테스트를 합니다.

int	array_int[8]	 = 
{
	3,
	2,
	9,
	10,
	11,
	22,
	44,
	22
};



Test4. '유니코드 문자열 배열' 읽고 쓰기

문자열의 배열을 쓰고 읽는 테스트를 합니다.

값 자체는 Test2와 동일하나 자료형이 배열로 되어 있다는 것만 다릅니다.

std::wstring	array_std_string_stdwstring[8]	 = 
{
	L"Please Let test this",
	L"이것 좀 테스트하게 해주세요.",
	L"这件事 试验",
	L"これを試ためさせてください",
	L"1234567!@#$%%^&}¢‡¥”w¯¥„ÈÉÞ´µ½²ÂÄÂÁ¾¿ÀÁÂ",
	L"Please 这件事 試ためさせてください 합시다.",
	L"Test What ever",
	L"1234"
};



Test5. Key(int)-Value(문자열)의 데이터의 쓰고  읽기

Key값이 문자열이고 Value값이 int의 배열인 데이터의 쓰고 읽기 테스트를 합니다.

std::map<std::wstring , std::vector<int>>	map_std_wstring_vector_int	 = 
{
	{L"zero",	{0,1,2,4}},
	{L"two",	{3,1,22,4}},
	{L"tree",	{4,1,12,4}},
	{L"fifteen",{5,1,82,4}},
	{L"five",	{7,1,22,4}},
	{L"eleven",	{10,21,12,34}}
};




2. 테스트 결과


테스트는 Windows7, Inter i7-377-K 3.5GHz, 16GByte 램 환경에서 했습니다.

여러 번 테스트 해본 결과 어느 정도 편차는 있지만 백만번이나 테스트하는 만큼 시행에 따라 큰 편차는 나지 않았었습니다.

결과는 각각 아래와 같습니다.


먼저 C#으로 CGD.buffer, protobuf, JSON으로 테스트한 결과 입니다.
Performance_04.PNG


C++로 제작한 CGD::buffer의 경우 아래와 같은 결과를 보입니다.

Performance_02.PNG



이 결과를 표로 정리해 보면 다음과 같습니다.


CGDBuffer_Bench.PNG


시간 아래 ~배로 표시한 것은 C++버전에 대한 성능비입니다.


테스트에서 알수 있는 것은 C++은 C#에 비해 압도적으로 성능이 좋다는 것을 알수 있습니다.

또 같은 C#이라도  JSON의 경우 모든 것을 문자열로 처리하다 보니 데이터 자체가 문자열인 경우는 그나마 차이가 적지만 그렇지 않은 경우 상당한 성능의 차이가 나는 듯합니다.

CGD.buffer의 성능은 protobuf보다 조금 우세하긴 하지만 여러 상황을 테스트 해봤을 때에 큰 차이가 나지 않는 수준이었습니다.

C#뿐만 아니라 C++ JSON이나 protobuf는 성능이 얼마나 되는지도 궁금하시겠지만 그기까진 미쳐 하지 못했습니다. ^ ^;

또 JSON은 어떤 라이브러리를 쓰느냐에 따라에서도 차이가 날수도 있어서 다양한 것을 테스트 해보고 싶었지만 protobuf와 JSON 벤치는 이미 알려진 것이 상당히 많은 만큼  하나의 라이브러리만을 테스트했습니다.

다음 번에는 좀 더 다양한 방법으로 벤치마크한 결과를 올리도록 하겠습니다.

(이 내용은 CGD::buffer의 UnitTest에 포함된 내용이니 궁금하신 분은 직접 해보셔도 됩니다.)