物理の駅 Physics station by 現役研究者

テクノロジーは共有されてこそ栄える

ROOT: TFile形式で1億イベントのtreeのIO(入出力)速度を圧縮形式で比較する

CERN ROOT の TTreeを TFileで入出力するときの処理時間を圧縮形式ごとに比較してみる。Pythonで同様のことをやった記事も参照。

8バイト(int64_t)✕8メンバー✕1億エントリーなので、圧縮なしの場合は6.4GBのデータサイズとなる。

圧縮形式 ファイルサイズ 出力時間 読み込み時間
無圧縮=0 6.40 GB 36 sec 14 sec
kZLIB=1 1.23 GB 63 sec 22 sec
kLZMA=2 0.24 GB 220 sec 59 sec
=3 1.23 GB 62 sec 23 sec
kLZ4=4 3.22 GB 37 sec 16 sec
kZSTD=5 0.56 GB 39 sec 25 sec

結果を見る限り、デフォルト kZLIB は圧縮率、時間のバランスはよくない。データの質にもよるが、kZSTD を選んでおけばほとんどのデータに対応できるだろう。ただし、ROOT6のZSTDで圧縮したファイルをROOT5で読むことは(たぶん)できない。

ROOTファイル出力のコード。データは圧縮しやすい内容にした。WindowsでVisual Studioでコンパイルして実行した。

void writeTreeToFile(std::string filename, int compressionAlgorithm = 1) {
    TFile* file = new TFile(filename.c_str(), "RECREATE");
    if (compressionAlgorithm == 0) {
        file->SetCompressionLevel(0);
    }
    else {
        file->SetCompressionAlgorithm(compressionAlgorithm);
    }
    TTree* tree = new TTree("tree", "Tree Title");

    int64_t x, y, ax, ay, ax0, ay0, ax1, ay1;

    // 1億本
    int N = 1 * 10000 * 10000;
    tree->Branch("x", &x, "x/L", N);
    tree->Branch("y", &y, "y/L", N);
    tree->Branch("ax", &ax, "ax/L", N);
    tree->Branch("ay", &ay, "ay/L", N);
    tree->Branch("ax0", &ax0, "ax0/L", N);
    tree->Branch("ay0", &ay0, "ay0/L", N);
    tree->Branch("ax1", &ax1, "ax1/L", N);
    tree->Branch("ay1", &ay1, "ay1/L", N);

    for (int i = 0; i < N; i++) {
        x = i;
        y = i;
        ax = i;
        ay = i;
        ax0 = i;
        ay0 = i;
        ax1 = i;
        ay1 = i;
        tree->Fill();
    }

    tree->Write();

    file->Close();
    delete file;
}

ROOTファイル読み込みコード

#include <TFile.h>
#include <TTree.h>
#include <iostream>
void readTreeFromFile(std::string filename) {

    TFile* f = new TFile(filename.c_str());
    TTree* tree = (TTree*)f->Get("tree");
    std::cout << tree->GetMaximum("x") << " ";
    std::cout << tree->GetMaximum("y") << " ";
    std::cout << tree->GetMaximum("ax") << " ";
    std::cout << tree->GetMaximum("ay") << " ";
    std::cout << tree->GetMaximum("ax0") << " ";
    std::cout << tree->GetMaximum("ay0") << " ";
    std::cout << tree->GetMaximum("ax1") << " ";
    std::cout << tree->GetMaximum("ay1") << " ";
    f->Close();
}

圧縮アルゴリズムのROOT上の定義

ROOT::RCompressionSetting::EAlgorithm::kZLIB; //ZLIB デフォルト
ROOT::RCompressionSetting::EAlgorithm::kLZMA; //LZMA Lempel-Ziv-Markov chain-Algorithm
ROOT::RCompressionSetting::EAlgorithm::kOldCompressionAlgo; // 古いの
ROOT::RCompressionSetting::EAlgorithm::kLZ4; //LZ4
ROOT::RCompressionSetting::EAlgorithm::kZSTD; //ZSTD