* DBM,File Readはどちらが早いか比較してみた。 [#k238dc2b]

たとえば、1kくらいのファイルが、ひとつのディレクトリーに大量にあった場合、ファイルリードが遅くなってくし、大量にiノードを消費してしまう。それを防ぐために、たとえば、20万ファイルくらい、同一のディレクトリにあった場合、それをファイルとして保存せずに、ひとつにDBMにkey=ファイル名、value=ファイル内容にしてしまうことも可能だ。
複数のファイルをひとつのDBMに格納した場合、速度低下はあるのだろうか?

** 28万ファイルをひとつのDBMに突っ込んでみた。 [#z5831f03]

28万ファイルのxmlをひとつのDBMにつっこんみた 大体1Gぐらいの大きさ。dbmはdbmhashである。

key=filename value=fileの内容になっている。

** DBM,ファイルリードを比べてみる。 [#z62c2eb7]
 time=5851 func=<function gen_smlist at 0xb7cc54fc>
 smidsize=17979
 time=174842 func=<function benchmark_dbm at 0xb7cbf7d4>
 time=269485 func=<function benchmark_file at 0xb7cc548c>

178秒(DBM)対269秒(FileRead)になっている。大体、2/3位になる。

** 結論 [#i88c4175]
小さなファイルをたくさん使う場合は、ファイルをそのまま保存するのではなく、DBMに入れるのもあり。


** ソース [#u05b0c95]
 #!/usr/bin/python
 # -*- coding:utf-8 -*-
 
 import anydbm
 from glob import glob
 import os
 import json
 import time
 import random
 
 src='../nicoran-data/thumbinfo/*.xml'
 json_src='../nicoran-data/json/*.json'
 src_dir='../nicoran-data/thumbinfo/'
 
 def import_dbm():
     l=glob(src)
     dbm=anydbm.open('thumbinfo.dbm','c')
     for i,f in enumerate(l):
         smid=os.path.basename(f).split('.')[0]
         dbm[smid]=open(f).read()
         if i%1000==0:
             print i,smid,f
     dbm.close()
 def import_test():
     dbm=anydbm.open('thumbinfo.dbm','r')
     print dir(dbm)
     k=dbm.items()
     print len(k)
 
 def time_profile(f):
     def inner_time(*args,**keys):
         t1=time.time()
         r=f(*args,**keys)
         t1=time.time()-t1
         print 'time=%d func=%s' % (t1*1000,f)
         return r
     return inner_time
 
    
 @time_profile    
 def benchmark_dbm(smlist):
     dbm=anydbm.open('thumbinfo.dbm','r')
     for smid in smlist:
         r=dbm[smid]
         len(r)
     dbm.close()
 
 @time_profile    
 def benchmark_file(smlist):
     for smid in smlist:
         smid=smid.encode('utf-8')
         smfile=src_dir+smid+'.xml'
         if os.path.isfile(smfile):
             a=open(smfile).read()
             k=len(a)
 
 @time_profile
 def gen_smlist(json_src):
     smlist=set()
     jds=glob(json_src)
     random.shuffle(jds)
     for jd in jds[:10]:
         jd=json.loads(open(jd).read())
         for a in jd:
             for l in a['ranklist']:
                 smid=l['smid']
                 smlist.add(smid.encode('utf-8'))
     return smlist
 
 def main():
     #import_dbm()
     #mport_test()
     smlist=gen_smlist(json_src)
     print 'smidsize=%d' % len(smlist)
     benchmark_dbm(smlist)
     benchmark_file(smlist)
 
 if __name__=='__main__':main()

トップ   差分 バックアップ リロード   一覧 単語検索 最終更新   ヘルプ   最終更新のRSS