조리법:EMF 퍼포먼스 팁

위클립스
이동: 둘러보기, 찾기

이 문서는 EMF XMLResource를 로드하고 세이브할 때 성능을 개선하는 몇 가지 방법들을 소개한다. 바쁜 사람은 권고안 절만 읽어도 무방하다.

목차

[편집] boolean 플래그를 사용하여 EMF모델의 메모리 사용량 줄이기

EMF 제네레이터는 여러 boolean 값들을 하나의 int 플래그 필드로 조합하도록 하는 옵션이 있다. 이는 모델의 boolean 속성들의 값과 unsettable로 지정된 피쳐들을 구분하는 플래그에 적용된다. 이 정책에 적용받을 수 있는 피쳐를 많이 가진 EObject의 경우, 이 설정을 통해 상당한 메모리 절감 효과를 얻을 수 있다.

이 기능을 사용하려면, 제네레이터 모델 편집기에서 "Model Feature Defaults"안의 "Boolean Flags Field" 속성에 플래그로 사용할 필드의 이름을 지정하면 된다.

"Boolean Flags Reserved Bits" 속성은 플래그용 int 필드가 실제로는 베이스 모델 구현객체로 부터 상속받은 것임을 나타내고, 베이스 모델 객체가 사용하기 위해 예약한 비트수를 나타낸다. 예를 들어 Ecore는 EObjectImpl에 정의된 eFalgs 필드를 사용하며 8비트가 예약되어있다. 예약되어 있다 하더라도 필요한 경우 이를 초과하여 사용할 권리가 예약되어 있기 때문에, 별도의 int 필드를 사용하는 것이 안전하며, 이 경우에도 상당한 메모리 절감효과를 볼 수 있다.

메모리 절감이 절박한 경우가 아니라면, 생성된 소스코드의 가독성이 나빠지므로 권장하지 않는다.

[편집] 로드 및 세이브 성능 개선하기

앞으로 소개할 옵션들(XMLResource에 정의 됨)은 load(InputStream, Map) 메서드와 save(OutputStream, Map)메서드 안에서 성능 및 메모리 사용량을 개선하기 위해 사용 될 수 있다.

[편집] 로드 옵션

설명
OPTION_DEFER_IDREF_RESOLUTION boolean

이 옵션을 켜면, 레퍼런스 리졸브(Resolving References)절차를 전체 문서가 파싱될 때 까지 연기시킨다. 기본 전략은 레퍼런스를 만날 때마다 리졸브를 시도하고, 맨 마지막에 리졸브에 실패한 레퍼런스들을 다시 리졸브한다. 이 접근 법은 아직 존재하지 않는 래퍼런스를 리졸브하려고 할 때, 리소스 내의 전체 객체를 뒤지며 시간을 낭비할 수 있다.

OPTION_USE_PARSER_POOL XMLParserPool

이 옵션은 파서 풀을 두어, SAXParser 인스턴스를 한 번만 만들고 재사용하게 한다. XMLParserPool은 파서를 얻고 릴리즈하는 간단한 인터페이스로 이뤄져 있다. 기본 구현인 XMLParserPoolImpl등과 같은 XMLParserPool이 지정되면 반복된 로드작업등과 같은 경우, 극적인 성능향상을 가져 온다. 파서 풀은 여러 리소스에 걸쳐 공유될 수 있으며, 기본으로 공급되는 구현은 스레드에 대해 안전하다.

OPTION_USE_XML_NAME_TO_FEATURE_MAP Map

이 옵션은 load()가 호출되는 동안 Qualified XML 이름(네임스페이스 + 로컬 이름)과 그에 해당하는 Ecore 피쳐의 매핑을을 캐시하여 공유하게 하며, 여러 리소스가 사용할 수도 있다. 이 옵션은 최초의 로드시에 캐시가 ExtendedMetaData나 XMLMap에 의해 영향을 받기 때문에, 이 연관을 분석하는 동안 약간 시간이 걸린다. 동일한 맵을 여러 로드에 걸쳐 제공하면, 최초의 로드를 제외하고 성능이 개선된다. 이 맵은 여러 리소스에 걸쳐 공유될 수 있으며, 충돌하는 Qualified XML Name이 없는 한 계속 이용할 수 있다.

[편집] 세이브 옵션

설명
OPTION_FLUSH_THRESHOLD Integer

이 옵션은 출력 스트림이 플러시가 일어나기 전까지 보존할 수 있는 문자의 개수를 지정할 수 있게 한다. 이 옵션은 큰 파일을 저장할 때, 메모리 사용량을 줄여주지만 기본 동작보다 느리게 만든다.

OPTION_USE_CACHED_LOOKUP_TABLE List

이 옵션은 모델 구성에 대한 캐시 정보를 담을 공간(Placeholder)을 지정할 수 있게 한다(Qualified XML Name을 캐시정보의 키로 이용한다). 다른 모델을 인스턴스를 저장하지 않는 한, 여러 리소스에 걸쳐 동일한 공간(Placeholder)이 공유될 수 있다.

OPTION_CONFIGURATION_CACHE Boolean

이 옵션은 반복되는 세이브 동작의 일반적인 데이터들을 캐시하고 재사용하게 하여, 이러한 데이터들의 초기화 비용을 억제한다. 이 옵션은 같은 모델의 인스턴스를 직렬화 하는 동안에만 안전하게 사용할 수 있다.

OPTION_FORMATTED Boolean

이 옵션을 이용하면 문서의 포맷을 비활성화 하여 줄바꿈 문자와 공백을 생략하여, 저장 속도를 높히고, 이후의 로드 속도도 개선한다. 이는 더 적은 길이의 바이트를 읽고 쓰는 것을 의미하지만, 직렬화된 문서의 가독성은 떨어진다.

OPTION_USE_FILE_BUFFER Boolean

이 옵션은 메모리 버퍼를 이용하는 대신 파일 버퍼를 이용해 출력물을 누적시킨다. 이는 메모리 사용량을 감소시키나 기본 동작보다 느리다.

역자주 세이브 및 로드 옵션은 동일한 리소스를 반복적으로 로드하거나, 같은 모델을 반복적으로 저장하는 등, 특수한 경우가 아니면, 큰 효과가 없다.

[편집] Resource 설정

XMLResource 인터페이스에는 없지만 XMLResourceImpl에는 setIntrinsicIDToEObjectMap(Map<String, EObject>)메서드가 있다. 이 메서드로 맵을 지정해 두면, 레퍼런스를 리졸브 할 때, 레퍼런스 아이디 대 EObject 맵을 사용하기 때문에, 리졸브과정이 훨씬 빨라진다. 이 맵이 지정되어 있지 않으면, 레퍼런스마다 전체 도큐먼트를 이터레이팅하며 리졸브를 시도하기 때문에 매우 비효율적이다. XMLResource를 개별 상속받아, 생성자에서 맵을 지정토록 할 것을 권장한다.

이 기능이 완전하게 작동하려면 모든 EClass는 ID로 설정된 피쳐를 가지고 있어야 한다. 그렇지 않은 경우, ResourceImpl#useUUID() 를 오버라이드 하여, 세이브 할 때 강제로 UUID를 발급받게 할 수도 있다.

[편집] 권고안

XMLResource를 기준으로 할 때 성능에 영향을 미치는 가장 큰 요소는 문서전체를 반복적으로 탐색해야 하는 레퍼런스 리졸빙이다. 나머지 요소들은 메모리 제약등이 없는 한, 큰 의미가 없는 성능 보정 요소들이다.

따라서 일반적으로는 다음의 두가지만 잘 기억하면 된다:

  1. XMLResourceImplsetIntrinsicIDToEObjectMap()을 이용하여 관계를 리졸브할 때 해시맵을 캐시로 이용하게 하도록 하자.
  2. 아직 문서에 등장하지 않은 관계 대상을 리졸브할 때는, 캐시 탐색 실패 후, 전체 문서를 뒤지게 될 것이므로, 이를 방지하기 위해 로드 옵션의 OPTION_DEFER_IDREF_RESOLUTION를 반드시 Boolean.TRUE로 지정하자.

이 기사에 대한 의견은 토론 페이지를 통해 나눌 수 있습니다.

개인 도구
이름공간
변수
행위
포탈
탐색
도움
도구모음