데이터 바인딩 프레임웍의 퍼포먼스 테스트를 위해 항공기 시간표 정보를 포함하고 있는 문서를 만들었다. 이들은 이전 글에서 정의했던 구조에 기반한다. 다음은 이 구조의 샘플이다. 이제부터는 데이터용 애트리뷰트를 사용하기 때문에 컴팩트(compact) 포맷으로 칭하겠다:
Listing 1. 컴팩트 문서 포맷
<?xml version="1.0"?>
<timetable>
<carrier ident="AR" rating="9">
<URL>http://www.arcticairlines.com</URL>
<name>Arctic Airlines</name>
</carrier>
<carrier ident="CA" rating="7">
<URL>http://www.combinedlines.com</URL>
<name>Combined Airlines</name>
</carrier>
<airport ident="SEA">
<location>Seattle, WA</location>
<name>Seattle-Tacoma International
Airport</name>
</airport>
<airport ident="LAX">
<location>Los Angeles, CA</location>
<name>Los Angeles International
Airport</name>
</airport>
<route from="SEA" to="LAX">
<flight carrier="AR" depart="6:23a"
arrive="8:42a" number="426"/>
<flight carrier="CA" depart="8:10a"
arrive="10:52a" number="833"/>
<flight carrier="AR" depart="9:00a"
arrive="11:36a" number="433"/>
</route>
<route from="LAX" to="SEA">
<flight carrier="CA" depart="7:45a"
arrive="10:20a" number="311"/>
<flight carrier="AR" depart="9:27a"
arrive="12:04p" number="593"/>
<flight carrier="AR" depart="12:30p"
arrive="3:07p" number="102"/>
</route>
</timetable> |
Listing 1의 공항 이름 정보는 코드에서 한줄 정도이다. 컬럼 사이즈에 맞추기 위해 몇 줄의 코드는 쪼개져서 두 줄로 나타난다.
컴팩트 포맷 외에도 데이터 값에 대한 자식 엘리먼트를 더 많이 사용하는 변이를 시도했다. 다음은 그 포맷에 나타난 같은 데이터이다. 여기서는 완전(full) 포맷이라고 칭하겠다:
Listing 2. 완전 문서 포맷
<?xml version="1.0"?>
<timetable>
<carrier ident="AR">
<rating>9</rating>
<URL>http://www.arcticairlines.com</URL>
<name>Arctic Airlines</name>
</carrier>
<carrier ident="CA">
<rating>7</rating>
<URL>http://www.combinedlines.com</URL>
<name>Combined Airlines</name>
</carrier>
<airport ident="SEA">
<location>Seattle, WA</location>
<name>Seattle-Tacoma International Airport</name>
</airport>
<airport ident="LAX">
<location>Los Angeles, CA</location>
<name>Los Angeles International Airport</name>
</airport>
<route from="SEA" to="LAX">
<flight carrier="AR">
<number>426</number>
<depart>6:23a</depart>
<arrive>8:42a</arrive>
</flight>
<flight carrier="CA">
<number>833</number>
<depart>8:10a</depart>
<arrive>10:52a</arrive>
</flight>
<flight carrier="AR">
<number>433</number>
<depart>9:00a</depart>
<arrive>11:36a</arrive>
</flight>
</route>
<route from="LAX" to="SEA">
<flight carrier="CA">
<number>311</number>
<depart>7:45a</depart>
<arrive>10:20a</arrive>
</flight>
<flight carrier="AR">
<number>593</number>
<depart>9:27a</depart>
<arrive>12:04p</arrive>
</flight>
<flight carrier="AR">
<number>102</number>
<depart>12:30p</depart>
<arrive>3:07p</arrive>
</flight>
</route>
</timetable> |
종종 XML 프레임웍의 관계 퍼포먼스는 사용되고 있는 문서들의 사이즈에 따라 크게 차이가 난다. 따라서 이 퍼포먼스 테스트에 큰 문서와 작은 문서 모두를 포함시켰다. 큰 문서(time-comp.xml과 time-full.xml)는 위에 보이는 두 개의 다른 포맷에 동일한 데이터 값을 사용한다. 때문에 크기가 상당히 달라진다. 작은 문서는 컬렉션에 있으면서 각각 사이즈가 컴팩트 포맷(ttcomp)의 경우 1.4-3.3 KB 이고 완전 포맷(ttfull)의 경우 2.2-5.8 KB 까지 이르는 34개의 문서들을 포함하고 있다. 큰 문서 처럼 작은 문서 컬렉션의 상응 문서들에는 같은 데이터 값이 포함되어 있다.
나는 이러한 결과에 사용된 두 개의 포맷 보다 문서 변이를 이용한 테스트를 선호한다. 하지만 데이터
바인딩 테스트에 더 많은 문서들을 추가할 때 들어가는 노력의 양은 상당하다. 여기에 사용된 두 개의 포맷은
적어도 데이터 바인딩 대안들이 전형적인 비지니스 문서에 대해 어떻게 수행되는 지를 매우 상징적으로 보여
줄 것이다. 아마도 매핑된 바인딩 접근방식을 사용하여 일반적인 문서의 전형 보다 더 많은 메모리가 사용되는
것을 알게된다. 이 문서의 대부분의 데이터 값이 프리머티브 유형으로 변환될 수 있기 때문이다. 이것은 매우
응축된 내부 구현으로 귀결된다. 대부분의 데이터 값이 String으로 유지 되어야
하는 곳에서 문서를 이용하면 매핑된 바인딩 접근방식에서 메모리 효율성은 감소하게 된다.
모든 테스트 시스템은 1.4GHz Athlon 시스템(256MB의 DDR RAM, RedHat Linux 7.2) 이다. 나는 Sun의 JDK 1.4.1 for Linux를 모든 테스트에 사용했다. 테스트를 받는 각 데이터 바인딩 프레임웍의 버전들은 다음과 같다;JAXB Beta 1, Castor 0.9.4.1, JBind 1.0 Beta 12/07, Quick 4.3.1, Zeus Beta 3.5.
데이터 바인딩과 다른 대안 방식 간 퍼포먼스 비교를 위해 SAX2 파서를 사용하여 같은 파일의 타이밍 테스트를 실행했다. 그리고 dom4j(dom4j version 1.3) 문서 모델을 사용하여 타이밍 테스트와 메모리 테스트를 실행했다.
타이밍 테스트와 메모리 사용 테스트용 프레임웍은 문서 모델을 이용한 이전 테스트 때와 같다. 이 벤치마크 프레임웍은 우선 모든 문서들을 내부 메모리 버퍼로 읽어온다. 그런다음 이 문서에 대한 인풋/아웃풋의 시간을 잰다. 인풋 타이밍와 아웃풋 타이밍에 나타난 테스트 결과는 최상의 시간이다. 이는 같은 코드가 반복적으로 실행되는 서버 유형 환경에서 장기 퍼포먼스의 대표적인 결과이다.
그림 1과 2 는 XML 문서를 읽고 dom4j 문서 모델과 다양한 데이터 바인딩 접근방식을 사용한 인메모리 구현을 만들 때의 타이밍 결과이다. 이 차트에서 첫 번째 타이밍 값(SAX2)을 문서를 파싱할 때의 기본 시간으로 보면된다. 이 문서 모델과 데이터 바인딩 구현은 파스 결과를 사용하여 메모리에 그들만의 구현을 만든다. 따라서 파서 보다 더 빠르지 않을 것이다. 코드 생성이 아닌 매핑에 근거한 이 두 개의 데이터 바인딩 테스트는 캡션에 기록해 두었다.
그림 1. 큰 문서를 메모리로 읽어오기
그림 2. 작은 문서를 메모리로 읽어오기
dom4j는 파서 단독으로 걸리는 총 시간의 두 배 이하로 문서의 인메모리 구현을 만들 수 있다. 이 퍼포먼스를 앞지르는 유일한 데이터 바인딩 프레임웍은 JiBX이다. JAXB, Quick, Zeus 모두 dom4j와 견줄만한 퍼포먼스 양상을 보인다. 하지만 거의 JiBX의 두 배이다. Castor는 비교해보면 매우 느리다. 매핑 바인딩과 코드 생성 모두 그렇다.
JBind는 이 테스트에서 대부분의 바인딩 프레임웍 보다 느리게 수행된다. 이러한 부진한 퍼포먼스의 작은 이유는 JBind 테스트에 쓰이는 느린 파서 때문이다. 큰 이유는 인풋 시 스키마에 대해 문서 밸리데이션을 강행하는 JBind 때문이다. 상당한 오버헤드가 걸린다. 부진한 퍼포먼스의 대부분은 JBind 프레임웍 자체에 기인한다.
JBind를 제외한 모든 테스트들은 전체 밸리데이션 없이 실행되었다. 대부분의 데이터 바인딩 프레임웍에는 고유의 밸리데이션 레벨이 포함되어 있다. 대부분 인풋 시 문서의 전체 검사를 위해 밸리데이션 파서를 사용할 수 있다. 그리고 어떤 것은 메모리에 바인딩 된 데이터에 대해 전체 밸리데이션을 수행할 수 있다.
그림 3과 4는 dom4j와 다양한 데이터 바인딩 접근방식을 사용 할 때 인메모리 구현의 XML 텍스트 직렬화 결과 시간이다.
그림 3. 메모리에서 큰 문서 작성하기
그림 4. 메모리에서 작은 문서 작성하기
dom4j는 이 부분에서 다른 어떤 데이터 바인딩 접근방식보다 나은 퍼포먼스를 보인다.
그림 5와 6은 메모리 사용에 대한 부분이다. 메모리에서의 실행은 매우 큰 문서(일반적으로 5+ MB)를 사용할 때 문제가 될 수 있다.
그림 5. 큰 문서의 메모리 사용
그림 6. 작은 문서의 메모리 사용
시간 퍼포먼스 비교 때보다 차이가 훨씬 크다. 그리고 패턴도 매우 다르다. 시간 측정 시 dom4j의 퍼포먼스가 좋았던 반면 메모리 사용 관점에서 보면 여느 다른 데이터 바인딩 프레임웍 보다 훨씬 나쁘다. 이 영역의 최고 퍼포먼스와 비교해 볼 때, dom4j는 같은 데이터를 나타내는데 10배의 메모리 이상이 필요하다.
이 두 개의 매핑된 바인딩 접근 방식은 바인딩된 데이터에 같은 내부 구조를 사용한다. 따라서 동일한 메모리
사용 양상을 보인다. 메모리 효율성 측면에서는 같다. 생성된 코드를 사용하는 데이터 바인딩 접근방식 보다
몇 배 더 나은 퍼포먼스이다. 이것은 매핑된 바인딩이 데이터 값에 대해 매우 응축된 구현을 사용하기 때문이기도
하다. 매핑된 바인딩은 이들 중 대부분을 int 값으로 변환한다. 변환의 오버헤드는
일기와 쓰기 시간에 추가된다. 하지만 메모리 사이즈 감소 외에는 별 효과가 없다. 실제로 데이터로 작업하는
경우 int는 String 보다 훨씬 편리하고 효율적이다.
매핑된 바인딩에서 프리머티브 값의 확장 사용외에도, 이러한 접근 방식이 가져다주는 메모리 효율성의 원인은 생성된 코드 접근방식이 각 바인딩 된 객체에 나타난 실제 데이터에 제어 정보를 추가하기 때문이다.
데이터 바인딩 프레임웍은 이 테스트에서 매핑된 바인딩의 메모리를 여러번 소비하지만 dom4j의 문서
모델 구현 보다는 훨씬 적다. dom4j 같은 문서 모델은 객체를 만들어 문서의 모든 컴포넌트를 나타내야하는
반면 데이터 바인딩은 실제 데이터만 보유하면 된다. 대부분의 데이터는 생성된 코드 바인딩과 함께 String으로서
저장되지만 어떤 값은 int와 다른 것으로 변환될 수 있다.
Zeus는 모든 데이터를 String으로 직접 저장한다. 일반적인 데이터 바인딩에서
가장 큰 메모리 사용률을 보이고 있다. JBind의 메모리 사용은 훨씬 크다. 내부적으로 사용되는 문서
모델이 부분적인 이유이기도 하다. 하지만 JBind에 사용되는 메모리 양은 문서 모델에 필요한 양 보다
몇 배나 많다l.
그림 1에서 6은 데이터 바인딩 프레임웍이 확장된 테스트 실행에서 어떤 퍼포먼스를 보이는지를 설명하고 있다. 단일 실행 환경에서 사용될 때 비교해 보는 것도 재미있는 일이다. 그림 7은 그 결과이다.
그림 7. 시작 시간
그림 7은 총 시간이다. 벤치마크 프로그램이 실행을 시작할 때 부터 라운드 트립 작동이 리턴될 때 까지. 이전 타이밍 그림과의 차이점은 데이터 바인딩 프레임웍 코드용 JVM에 의해 클래스로딩과 원시 코드 생성에 대부분의 시간이 쓰여진다는 점이다.
데이터 바인딩 프레임웍에 의해 사용된 jar 파일의 크기는 시작 시간에 주요하게 영향을 미치는 한 요인이다. JiBX는 가장 작고, JAXB, Castor, JBind가 가장 크다.
- developerWorks worldwide 사이트에서 이 기사에 관한 영어원문.
-
Part
1.
-
Download.
- "Data
Binding with Castor" (developerWorks,
April 2002).
-
developerWorks "Introduction
to XML" 튜토리얼(August 2002).
-
developerWorks 기술자료: XML document model performance in Java
(September 2001) & 자바에서의 XML: 상이한 자바 XML 문서 모델들이 작동하는 방식
(February 2002).
- "Converting
between Java objects and XML with Quick".
-
"Getting
started with Castor JDO" : Bruce Snyder (developerWorks,
August 2002).
-
Java
Data Objects (JDO) API.
-
Java
Technology and XML.
-
JSR
31 - the XML Data Binding Specification.
- developerWorks XML
& Java
technology zone.
-
IBM Certified Developer in XML and related technologies.
Dennis Sosnoski: Sosnoski Software Solutions, Inc