michgan software studio

'encoding'에 해당되는 글 2건

  1. 2009/11/25 인코딩 변환 라이브러리 속도 테스트
  2. 2009/11/12 인코딩 변환 라이브러리 만들기
직접 만든 인코딩 변환 라이브러리의 속도를 테스트해보았습니다. MBCS에서 UNICODE로 혹은 그 반대로 매핑하는 2차원 배열을 만들어 놓고 참조하는 방식입니다. 테이블 데이타를 static 형식으로 코드에 삽입시켰더니, exe 파일이 400-500 kb 정도가 되는군요. (코드 페이지 = 932, 936, 949, 950)

꽁수를 안 쓰고 2바이트 매핑 테이블을 그대로 탑재시키면, 1M 정도였을 겁니다. 지금은 바이트 범위를 조사해서 필요 없는 부분은 저장하지 않는 방식을 사용합니다. gz 스트림으로 압축시키면 실행 파일의 크기를 더 줄일 수 있기(333k에서 256k로)는 한데, 용량 감소폭 대비 번거로움을 따져보면 그냥 쓰는게 나을거 같습니다.

아무튼 직접 만든 인코딩 변환 라이브러리의 속도를 비교해봅시다. 비교 대상은 System.Text.Encoding 객체입니다. libiconv도 하고 싶으나 솔직히 귀찮습니다.

400kb 정도 되는 한글 텍스트 파일(243943 유니코드 글자)을 가지고 MBCS로 인코딩하고 디코딩하는 속도를 재었습니다. 5번 재어서 평균 냈고 사용한 기종은 소니 엑스페리아 X1, Windows 6.1 한글판입니다. 컴파일러는 VisualStudio 2008 sp1 + Windows Mobile 6 SDK 입니다.

단위는 msec.
  내거 Enc  내거 Dec  C# Enc  C# Dec 
 Unicode   19 19   25    25 
 UnicodeBE   49 51  132    72 
 UTF-8   60  86    88  134 
 CP949 160  77  214    52 

Encoding: Unicode -> MBCS. 즉, WideCharToMultiByte
Decoding: MBCS -> Unicode, 즉, MultiByteToWideChar

의외로 MS가 제공하는 라이브러리가 느렸군요.

생각보다 C#이 빠르다는 사실을 알 수 있습니다. 물론 빠른 속도를 내기 위해서 코드를 좀 간결하게 바꾸는 작업을 진행하긴 했지만 말입니다. 이것이 바로 JIT의 힘입니다. 좋군요.
저작자 표시 비영리 동일 조건 변경 허락


프로젝트를 진행하다 보면 텍스트 인코딩을 변환해야하는 경우가 있습니다. 일반적으로 win32 환경이라면 MultiByteToWideChar() 이라는 함수를 사용해서 유니코드 문자열로 변환하게 됩니다. 리눅스나 스크립트 언어 환경이라면 iconv() 함수를 사용하게 되겠죠.

문제는 win32 환경인데 MultiByteToWideChar() 함수가 통하지 않는 환경입니다. 예를 들어 PocketPC 에서는 OS 언어와 UTF-8 인코딩에 대한 변환만 지원할 뿐입니다. 이럴 경우에는 어떻게 하느냐? 가 이번 포스트의 주제입니다.


첫번째 방법은 제가 작년에 사용한 "libiconv 라이브러리 포팅하기"입니다. 말 그대로 win32 환경으로 포팅하는 방법이죠. 원래 libiconv는 win32 네이티브 컴파일을 지원했기 때문에 포팅하기가 생각보다 쉽습니다. 관심 있으신 분들은 해당 포스트로 가셔서 보시기 바랍니다.

두번째 방법은 지금 제가 적용하고 있는 방법입니다. "내 프로젝트에는 GPL처럼 독이 묻은 라이센스를 포함할 수 없다!"라고 생각하신다면 직접 만들어 쓰시는 수 밖에 없겠죠. libiconv의 경우에는 다행히 LGPL 라이센스이긴 합니다만, 그래도 왠지 고기 먹고 이를 닦지 않은 듯 개운하지는 않습니다.

직접 만든다고 했을 때 가장 문제가 되는 점은 MBCS 문자에서 유니코드 문자로의 코드 매핑을 알아내는 점입니다. 이 테이블만 구할 수 있다면 텍스트 변환 라이브러리의 작성은 거의 70% 정도가 끝났다고 볼 수 있습니다.

그리고 다행히도 코드 변환 테이블이 인터넷에 공개되어 있습니다. 무려 마이크로소프트 사가 제공한 정보입니다. 아래의 링크는 cp949(=한국어)에 대한 매핑 테이블입니다. cp932(=일본어)나 중국어도 쉽게 찾을 수 있습니다.
http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP949.TXT

테이블은 일관성 있는 규칙으로 작성되어 있기 때문에 이것을 읽어들이는 유틸은 손쉽게 작성할 수 있습니다.

다음은 위 자료를 읽기 위한 간단한 perl 스크립트입니다. 이 세상에서 텍스트 파일을 이렇게 간단하게 파싱할 수 있는 언어는 perl 밖에 없을거 같네요.

#!perl -w

open(X, "<cp949.txt" );
my @x = grep {!/^\#/} <X>;
close( X );
chomp( @x );

foreach my $y ( @x )
{
    my @a = split( /\t/, $y );
    if ( $#a == 2 )
    {
        printf( "%s -> %s\n", $a[0], $a[1] );
    }
}

cp949 에 대해 적용해보면 17304 개의 매핑을 얻을 수 있습니다.

이 데이타를 토대로 1:1 매핑하는 코드를 작성하는 것은 별로 어렵지 않을 것입니다.

C# 으로 cp932, 936, 949, 950 에 대해 MBCS to UNICODE 매핑 테이블을 작성한 후에 컴파일 하면 대충 160kb 정도의 바이너리가 만들어집니다.

이렇게 만든 변환 코드와 win32 API와의 속도 차이에 대해서는 다음에 기회가 있으면 포스팅하도록 하지요.

저작자 표시 비영리 동일 조건 변경 허락

1 
BLOG main image
michgan software studio
Copyright (c) 1992-2008 michgan
by michgan

카테고리

분류 전체보기 (60)
release (34)
document (23)
review (1)