<h2>记忆结构</h2>
<p>从未使用过pytables,但查看源代码:</p>
<pre><code>class _Deadnodes(lrucacheExtension.NodeCache):
pass
</code></pre>
<p>因此,看起来死节点是使用LRU缓存实现的。LRU==“最近最少使用”这意味着它将首先丢弃最少使用的节点。源是<a href="https://github.com/PyTables/PyTables/blob/develop/tables/lrucacheExtension.pyx" rel="nofollow noreferrer">here</a>。在</p>
^{pr2}$
<p>它们将其用作在程序中实际运行和表示的节点的自定义字典。在</p>
<p>非常简单的示例(节点是字母,缓存中的数字表示条目的过时程度):</p>
<pre><code>memory of 4, takes 1 time step
cache with size 2, takes 5 times steps
disk with much much more, takes 50 time steps
get node A //memory,cache miss load from disk t=50
get node B // "" t=100
get node C // "" t=150
get node D // "" t=200
get node E // "" t=250
get node A //cache hit load from cache t=255
get node F //memory, cache miss load from disk t=305
get node G //memory, cache miss load from disk t=355
get node E // in memory t=356 (everything stays the same)
t=200 t=250 t=255
Memory CACHE Memory CACHE Memory CACHE
A E A0 E B0
B B A
C C C
D D D
t=305 t=355
Memory CACHE Memory CACHE
E B1 E G0
A C0 A C1
F F
D G
</code></pre>
<p>如你所知,在现实生活中,这些结构是巨大的,访问它们所需的时间是以总线周期为单位的,所以1/(你电脑的时钟)。在</p>
<p>相对而言,访问元素所需的时间是相同的。对于内存来说,这几乎可以忽略不计,对于缓存来说,这一点可以忽略不计,而对于磁盘来说,这一点要多得多。从磁盘读取是整个过程中最长的部分。磁盘和手臂需要移动等等。这是一个物理过程,而不是一个电子过程,因为它不是以光速发生的。在</p>
<p>在pytables中,它们做了类似的事情。他们用Cython编写了自己的缓存算法,Cython是活动节点(内存)和完整数据(磁盘)之间的中间人。如果命中率太低,那么看起来缓存将被关闭,在一定的循环数之后,它将再次打开。在</p>
<p>在<a href="https://github.com/PyTables/PyTables/blob/develop/tables/parameters.py#76" rel="nofollow noreferrer">parameters.py</a>中,<code>DISABLE_EVERY_CYCLE</code>、<code>ENABLE EVERY_CYCLE</code>和<code>LOWEST_HIT_RATIO</code>变量用于定义在最低命中率下要禁用的循环数和等待重新启用的循环数。不鼓励更改这些值。在</p>
<p>您应该从中得到的主要信息是,如果需要对大型数据集进行处理,请确保它们位于相同的节点上。如果你能逃脱惩罚,读入一个块,在那个卡盘上进行处理,得到你的结果,然后加载另一个块。如果加载块A,获取另一个块B,然后再次加载块A,这将导致最大的延迟。一次只对一个数据块进行操作,并将访问和写入保持在最低限度。一旦一个值在<code>_alivenodes</code>中,修改它会很快,<code>_deadnodes</code>会慢一点,两个都不会慢很多。在</p>
<h2>节点缓存插槽</h2>
<p><code>params['NODE_CACHE_SLOTS']</code>定义死节点集的大小。追溯到<a href="https://github.com/PyTables/PyTables/blob/develop/tables/parameters.py#L161" rel="nofollow noreferrer">parameters.py</a>,默认为64。它说明你可以尝试不同的值并返回报告。您可以更改文件中的值,也可以执行以下操作:</p>
<pre><code>import parameters
parameters.NODE_CACHE_SLOTS = # something else
</code></pre>
<p>这只会限制缓存中保存的节点数。如果没有,您将受到python堆大小的限制,请设置为<a href="https://stackoverflow.com/questions/2308091/how-to-limit-python-heap-size">this</a>。在</p>
<h2>追加/刷新</h2>
<p>对于<code>append</code>,<code>flush</code>确保将行输出到表中。你用它移动的数据越多,数据从内部缓冲区移动到数据结构所需的时间就越长。它正在用其他处理代码调用<a href="http://www.hdfgroup.org/HDF5/doc/HL/RM_H5TB.html#H5TBwrite_records" rel="nofollow noreferrer">H5TBwrite_records</a>函数的修改版本。我猜调用的长度决定了输出周期的长度。在</p>
<p>请记住,这都是源代码,不要考虑他们试图做的任何额外的魔术。我从未使用过pytables。理论上,它不应该崩溃,但我们并不生活在一个理论世界里。在</p>
<p>编辑:</p>
<p>实际上,我自己也发现了pytables的需求,我在他们的faq中遇到了<a href="http://www.pytables.org/moin/FAQ#Ifitisdesignedtodealwithverylargedatasets.2CthenPyTablesshouldconsumealotofmemory.2Cshouldn.27tit.3F" rel="nofollow noreferrer">this question</a>,这可能会回答您的一些顾虑。在</p>
<p>感谢您向我公开了pytables,如果我在研究这个问题之前遇到了<code>.h5</code>个文件,我就不知道该怎么做了。在</p>