首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >pyROOT中巨大的内存使用量

pyROOT中巨大的内存使用量
EN

Stack Overflow用户
提问于 2017-09-12 13:51:35
回答 1查看 796关注 0票数 1

我的pyROOT分析代码使用了大量的内存。我将问题简化为下面的示例代码:

代码语言:javascript
复制
from ROOT import TChain, TH1D

# Load file, chain
chain = TChain("someChain")
inFile = "someFile.root"
chain.Add(inFile)

nentries = chain.GetEntries()

# Declare histograms
h_nTracks = TH1D("h_nTracks", "h_nTracks", 16, -0.5, 15.5)
h_E = TH1D("h_E","h_E",100,-0.1,6.0)
h_p = TH1D("h_p", "h_p", 100, -0.1, 6.0)
h_ECLEnergy = TH1D("h_ECLEnergy","h_ECLEnergy",100,-0.1,14.0)

# Loop over entries
for jentry in range(nentries):
   # Load entry
   entry = chain.GetEntry(jentry)

   # Define variables
   cands = chain.__ncandidates__
   nTracks = chain.nTracks
   E = chain.useCMSFrame__boE__bc
   p = chain.useCMSFrame__bop__bc
   ECLEnergy = chain.useCMSFrame__boECLEnergy__bc

   # Fill histos
   h_nTracks.Fill(nTracks)
   h_ECLEnergy.Fill(ECLEnergy)

   for cand in range(cands):
      h_E.Fill(E[cand])
      h_p.Fill(p[cand])

其中someFile.root是一个根文件,每个条目有70万个条目和多个粒子候选项。

当我运行这个脚本时,它使用了大约600 MB的内存。如果我把线移开

代码语言:javascript
复制
h_p.Fill(p[cand])

它使用的是400 MB。

如果我也移除线

代码语言:javascript
复制
h_E.Fill(E[cand])

它使用150 MB。

如果我也移除这些线

代码语言:javascript
复制
h_nTracks.Fill(nTracks)
h_ECLEnergy.Fill(ECLEnergy)

内存使用量没有进一步减少。

似乎我填写的每一个额外的直方图

代码语言:javascript
复制
h_variable.Fill(variable[cand])

(即,每项候选人填写一次的直方图,而不是每项只填写一次的直方图),我使用额外的~200 MB内存。这成为一个严重的问题,当我有10个或更多的直方图,因为我使用的内存的GBs,我超过了我的计算系统的限制。有谁有解决办法吗?

更新:我认为这是一个python3问题。

如果我在最初的文章中使用脚本(上面)并使用python2运行它,那么内存使用量是200 MB,而使用python3的是大约600 MB。即使我试图通过使用长变量名来复制问题2,与python2相比,作业仍然只使用大约200 MB的内存,而使用python3的则是~1.3GB。

在我的谷歌搜索中,我发现了其他几个人在使用pyROOT和python3时遇到内存泄漏的情况。从Python3.6.2和根6.08/06来看,这似乎仍然是一个问题,如果您想要使用python2,那么暂时必须使用pyROOT。

因此,就目前而言,使用python2似乎是我的“解决方案”,但并不理想。如果任何人有任何进一步的信息或建议,我将非常感谢您的意见!

EN

回答 1

Stack Overflow用户

发布于 2017-10-04 13:25:19

我很高兴你发现Python3是问题所在。但是,如果您(或任何人)在将来使用直方图时仍然存在内存使用问题,下面是一些可能的解决方案,希望您能找到帮助!

THnSparse

使用THnSparse--THnSparse是一种有效的多维直方图,它在只有一小部分总桶被填充的直方图中显示了它的优势。你可以在这里读到更多关于它的内容。

TTree

TTrees是根中的数据结构,坦率地说,这些数据结构美化了表。然而,它们是高度优化的。TTreebranchesleaves组成,其中包含可以通过根快速有效地访问的数据。如果您首先将数据放入TTree中,然后将其读取到直方图中,我保证您会发现内存使用率更低,运行时间更长。

下面是一些示例TTree代码。

代码语言:javascript
复制
root_file_path = "../hadd_www.root"

muon_ps = ROOT.TFile(root_file_path)
muon_ps_tree = muon_ps.Get("WWWNtuple")
muon_ps_branches = muon_ps_tree.GetListOfBranches()
canv= ROOT.TCanvas()

num_of_events = 5000

ttvhist = ROOT.TH1F('Statistics2', 'Jet eta for ttV (aqua) vs WWW (white); Pseudorapidity',100, -3, 3)
i = 0

muon_ps_tree.GetEntry(i)
print len(muon_ps_tree.jet_eta)

#sys.exit()
while muon_ps_tree.GetEntry(i):
    if i > num_of_events: break
    for k in range(0,len(muon_ps_tree.jet_eta)-1):
        wwwhist.Fill(float(muon_ps_tree.jet_eta[0]), 1)
    i += 1  

ttvhist.Write()
ttvhist.Draw("hist")
ttvhist.SetFillColor(70);

这里有一个资源,您可以在这里了解TTree的奇妙之处:

TTree根文档

对于更多的阅读,这里有一个关于加速在CERN帮助论坛上构建根历史图的讨论:

内存-用于DQ监视的保守直方图

祝您的数据分析顺利,代码编写愉快!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46178244

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档