Schema.getGlobalDescribe()
Apex로 개발하다 보면 다이내믹한 코드를 만들기 위해 Schema의 하위 클래스들을 사용할 때가 많습니다.
그중 가장 대표적인 방식이 바로 Schema.getGlobalDescribe()가 아닐까 싶습니다.
필요한 SObjectType을 get 해서 얻기 쉽고, 여러 SObject에 대해 반복해서 사용할 수도 있습니다.
이 메서드는 각종 질문에 대한 답변으로 가장 자주 등장하기도 하면서, 동시에 많은 논쟁거리이기도 합니다.
모든 SObjectType에 대한 내용을 한 번에 가져오기 때문에 비용이 크다는 이유에서 입니다.
그렇다면 다른 방식들과 비교했을 때, 정말 눈에 띄게 비용이 발생하는지 알아보려고 합니다.
대상
아래 3가지를 비교해 보겠습니다.
달라 보이지만 모두 같은 결과(DescribeSObjectResult)를 얻기 위한 코드입니다.
차이를 명확하게 하기 위해 각 실행마다 500회 반복합니다.
- Schema.getGlobalDescribe()
String obj = 'Account';
Map<String, Schema.SObjectType> gd = Schema.getGlobalDescribe();
for (Integer i = 0; i < 500; i++) {
Schema.SObjectType sobjType = gd.get(obj);
Schema.DescribeSObjectResult describeResult = sobjType.getDescribe();
}
- Schema.describeSObjects()
String obj = 'Account';
String[] types = new List<String>{ obj };
for (Integer i = 0; i < 500; i++) {
List<Schema.DescribeSobjectResult> describeResults = Schema.describeSObjects(types);
}
- Type.forName()
String obj = 'Account';
for (Integer i = 0; i < 500; i++) {
SObjectType sobjType = ((SObject) Type.forName('Schema', obj).newInstance()).getSObjectType();
DescribeSObjectResult describeResult = sobjType.getDescribe();
}
방법
다음과 같은 단순한 방식으로 CPU time과 Heap을 측정하겠습니다.
Integer startTime = Limits.getCpuTime();
Integer startHeap = Limits.getHeapSize();
// your code here
Integer endTime = Limits.getCpuTime();
Integer endHeap = Limits.getHeapSize();
Integer timeResult = endTime - startTime;
Integer heapResult = endHeap - startHeap;
결과
CPU TIME (*5회 평균)
CPU TIME | DE | Prod | Scratch |
Schema.getGlobalDescribe() | 6198 | 8516.6 | 9219.4 |
Schema.describeSObjects() | 12.8 | 11.8 | 14.6 |
Type.forName() | 53.8 | 58.6 | 45.8 |
HEAP SIZE
HEAP SIZE | DE | Prod | Scratch |
Schema.getGlobalDescribe() | 24510 | 21647 | 26436 |
Schema.describeSObjects() | 101 | 101 | 101 |
Type.forName() | 121 | 121 | 121 |
결론
Schema.getGlobalDescribe()은 다른 두 방식에 비해 훨씬 더 많은 CPU time과 Heap을 소모합니다.
실험에서 500회 반복했다는 점을 감안하자면, 단순히 1회 호출하는 것만으로는 전체 프로세스에서 큰 비중을 차지하진 않을 수 있습니다. 하지만 다른 방식들을 제쳐두고 선택해야만 하는 이유는 찾기 어려워 보입니다.
Schema.getGlobalDescribe()는 꼭 필요한 경우에만 반복 호출을 피해 사용하고,
그 외 경우에는 가급적 Schema.describeSObjects()와 Type.forName()를 사용하도록 합시다.
Post by 강성호