인터넷을 둘러 보다가 C++와 C#, Java, 그리고 Node.js 정렬 성능 비교란 흥미로운 글을 발견했다. 글에서는 크기가 1백만인 int[]
배열로 벤치마크를 하고 있었는데, 소스를 약간 고쳐서 자바 ArrayList<Integer>
와 C# List<int>
간에는 얼마 만큼의 성능차가 나는지 알아 보았다.
자바
static void quicksort(ArrayList<Integer> a, int start, int end) {
if (end - start < 2) {
return;
}
int p = a.get(start + (end - start) / 2);
int l = start;
int r = end - 1;
while (l <= r) {
if (a.get(l) < p) {
++l;
continue;
}
if (a.get(r) > p) {
--r;
continue;
}
int t = a.get(l);
a.set(l, a.get(r));
a.set(r, t);
++l;
--r;
}
quicksort(a, start, r + 1);
quicksort(a, r + 1, end);
}
quicksortThreeway()
도 수정한 방법은 거의 같으므로 생략. 자바는 인덱서([]
)를 제공하지 않아서 단지 int[]
를 ArrayList<Integer>
로 바꿨을 뿐인데도 소스를 거의 절반은 고쳐야 했다.
C#
static void Quicksort(List<int> a, int start, int end)
{
if (end - start < 2)
{
return;
}
var p = a[start + (end - start) / 2];
var l = start;
var r = end - 1;
while (l <= r)
{
if (a[l] < p)
{
++l;
continue;
}
if (a[r] > p)
{
--r;
continue;
}
var t = a[l];
a[l] = a[r];
a[r] = t;
++l;
--r;
}
Quicksort(a, start, r + 1);
Quicksort(a, r + 1, end);
}
C#은 한 줄만 고치면 되었다.
벤치마크 결과 및 분석
int
타입은 개당 4바이트라 백만개 짜리 리스트라고 해도 전체가 4MB 밖에 안된다. 캐시 영향을 최소화하기 위해 이 테스트에서는 원소 개수를 천만개로 늘렸다.
결과가 꽤 흥미로운데, 일단 “Built-in”이라고 되어 있는 int[]
벤치마크 항목에선 자바가 C#보다 25% 빠르다. 그 이유는 아마도 자바의 Timsort가 .NET의 Introsort보다 효율적이어서인 것 같다. .NET도 자바 버전을 그대로 이식한 C# 버전이 있으니 다음번엔 그걸로 비교해 보는 것도 좋겠다.
반면 자바 ArrayList<Integer>
와 C# List<int>
를 대상으로 한 나머지 두 테스트에서는 C# 쪽이 2-웨이는 170%, 3-웨이는 282% 빨랐다. 자바에서는 int
같은 타입의 원소를 리스트에 넣으려면 꼭 박싱(프리미티브 타입을 레퍼런스 타입으로 포장하는 것)을 거쳐야 한다. 그 결과 성능이 엄청나게 희생되는 걸 볼 수 있다. 그렇지만 C#과 자바 양쪽 모두 배열을 쓴 쪽이 압도적으로 빠른 것도 눈여겨 볼 점이다. 대량의 데이터 정렬은 리스트 대신 배열로 하는 게 유리하다는 결론.
댓글 없음:
댓글 쓰기
댓글을 입력하세요. 링크를 걸려면 <a href="">..</a> 태그를 쓰면 됩니다. <b>와 <i> 태그도 사용 가능합니다.
게시한지 14일이 지난 글에는 댓글이 등록되지 않습니다. 날짜를 반드시 확인해 주세요.