10억 행 챌린지(The One Billion Row Challenge)

10억 행 챌린지(The One Billion Row Challenge)는 현대 Java를 이용해서 10억 행의 텍스트 파일을 얼마나 빨리 집계할 수 있는지를 살펴보는 탐구 입니다.

이 첼린지의 .NET 버전도 있습니다!


7개의 좋아요
3개의 좋아요

각 챌린지에서 탑 랭커의 속도가 닷넷이 많이 앞서는데, 그걸 그대로 받아 들일 수 있는지 의문스럽네요.

3개의 좋아요

저도 비교 실행해보지는 않아서 뭐라 말할 수는 없지만 Java보다 .NET C#이 메모리 최적화와 속도 최적화에 좀 더 앞선 것으로 아는데요, 그 결과가 아닐까 살며시 생각해봅니다.

시간 될 때 C#으로 일반적인 방법을 써서 결과를 내보고 싶네요

3개의 좋아요

맥에서는 파일 io에 대한 속도가 윈도우 대비 빠르게 나오는 부분이 있습니다.
애플 자체의 파일 테이블 시스템과 연계되어 있는 부분인데 깃헙의 결과 테이블에 net8/wasm 부터는 속도가 2분 이상으로 떨어지는게 바로 파일 읽는 방식이 달라지기 때문입니다.

실제로 파일 내부를 쓰거나 하지 않는 이상 마치 처리된것 처럼 보이게 하는 것도 있습니다.

일전에 대용량 파일을 생성 및 삭제하는 테스트를 해본적이 있는데
윈도우에는 실제로 파일 내부 바이너리를 다 채우고 io가 종료되는때까지의 시간이 기록되어서 오래걸리는걸로 확인됐지만, 맥에서는 파일 구조설정 및 공간 예약까지만 하고 끝내는 듯한 그런 모습으로(마치 비동기처리 되는것같은 느낌) 처리되는것 같았습니다. 그래서 두 os간 속도 차가 컸습니다.

제가 글을 잘 못적는데,
맥에서는 파일 io 처리 방식이 독특해서 속도가 굉장히 빨라 보인다 라는 점을 말씀드리고 싶었습니다.

6개의 좋아요

.net 이 java보다 퍼포먼스가 좋다는것은 여기가 닷넷 커뮤니티라 하는 말이 아니라
유명한 얘기입니다.
심지어 자바 컨퍼런스 할때 닷넷 관계자들이 당당히 가서 퍼포먼스 자랑하는 마케팅도 벌인적이 있을정도로
아무래도 글로벌 회사인 MS 에 기준에 HW 업체들이 맞추고 공식적인 정보나 HW를 C언어 기준으로 최적화
하는 경우가 많아서 그런것이 아닐까 싶네
구글에 java vs .net performance benchmark 이렇게 검색해도 대부분 속도면에서 우위를 말하는 아티클이 많죠

2개의 좋아요

궁금해져서 프로젝트 클론하고 measurements.txt 파일을 생성해서 잠깐 살펴봤는데 용량이 12.8GB 군요! -_-;;;; 일반적인 방법으로는 2~3초대 절대로 나올 수 없는 크기군요!

2개의 좋아요

다음의 구조로

class MeasurementAggregator
{
    public double Min { get; set; } = double.MaxValue;
    public double Max { get; set; } = double.MinValue;
    public double Sum { get; set; }
    public long Count { get; set; }
}

Dictionary를 이용해서 최소, 최대, 합계, 개수를 저장하는 일반적인 코드를 작성한 후

var count = 0;
var dic = new Dictionary<string, MeasurementAggregator>();
while (true)
{
    var line = await file.ReadLineAsync();
    if (line is null)
        break;

    var (zoneName, strTemp) = line.Split(';') is string[] splits ? (splits[0], splits[1])
        : throw new Exception("Invalid line format");

    var bResult = dic.TryGetValue(zoneName, out var zone);
    if (bResult is false)
        zone = new MeasurementAggregator();

    var temp = double.Parse(strTemp);
    zone!.Min = Math.Min(zone!.Min, temp);
    zone!.Max = Math.Max(zone.Max, temp);
    zone!.Sum += temp;
    zone!.Count++;
    
    count++;

    if (count % 10000000 is 0)
    {
        Console.WriteLine($"{count}: {zoneName}|{strTemp}");
    }
}

i9-12900H, n.2 nvme
.NET 8, Release, x64로 컴파일 실행했을 때 140,638 ms (2.34 분) 걸리네요.

2~3초는 어떻게 나오는 걸까요? ;;

2개의 좋아요

파일이 12기가 가량이니까, 3초가 나올려면 적어도 초당 5기가는 읽어들이고 그와 동시에 처리되어야 하지 않을까 싶네요. 재밌겠네요 나중에 한번 해봐야겠습니다.

2개의 좋아요

아무리 그래도, 3초만에 12GB를 처리하는 것은 매우 어렵지 않나요?

2개의 좋아요

닷넷 버전은 맥을 사용한 것을 확인할 수 있는데, 자바의 경우 동일하게 맥에서 사용한 것인지 확인이 안되어서, 수치를 그대로 받아 들이기 어렵습니다.

만약, 동일 사양 컴퓨터에서 JDK 와 .Net Sdk 를 모두 설치하고 실행해 봐야 어느 것이 더 빠르다고 할 수 있지 않을까요?

2개의 좋아요

1BRC in .NET among fastest on Linux: My Optimization Journey · Victor Baybekov (hotforknowledge.com)

C++ 과 rust 의 중간이군요.

4개의 좋아요
2개의 좋아요
3개의 좋아요

요즘 이 프로젝트에 매료되신 것 같네요.

덕분에, 즐겁게 벤치마크 결과를 보고 있습니다.
특히, C++, 러스트 보다 빠르다는 점이요. ^^

해당 프로젝트의 코드를 보고 이해하는 게 너무 어려운 게 함정이지만요. ㅠㅠ

3개의 좋아요