我是自学成才,对于将对象加载分成循环中的单独部分的术语或具体改进(如果有的话)不太确定。
例如,我使用rails,最近我遇到了一个问题,即我一次加载了太多重的ActiveRecord对象,并在rails API中找到了这个问题:http://api.rubyonrails.org/classes/ActiveRecord/Batches.html
find_in_batches
的作用是将查询分成多个子集,因此不是制作一个大型查询,而是制作10个小查询,而不是一次加载这么多对象。
例如:
def batch_process
Car.find_in_batches do |batch|
batch.each(&:start_engine!)
end # at the end of each iteration, is the memory from the current batch deallocated?
end
def start_all_at_once
Car.all.each(&:start_engine!)
end
我的问题是,这样做有什么好处?从概念上讲,我理解一次加载较少允许在每个循环中释放内存(这是正确的??),但究竟是什么改进了?我相信这是最高内存消耗,但这是否会转化为RAM / CPU使用率的改进(不确定RAM / CPU之间的区别是诚实的)?或者与垃圾收集或Ruby堆大小有关?
试图了解较低级别的细节。谢谢!
答案 0 :(得分:4)
假设您想要处理数据库中的100万条记录。
首先,您的数据库需要加载并向您的Ruby应用程序发送100万条记录。然后Rails需要解析那100万条记录(这会使用内存),然后生成100万条记录和一个包含所有内容的大数组。这将使用大量处理能力(CPU)和内存(RAM)来存储它们。
让我们说每条记录需要1KB的内存(这是一个任意数字)。然后100万将占用1GB内存,我们甚至不计算数据库使用的内存,传输和转换。
现在,分批加载100万条记录。然后,您的数据库一次只加载和传输1000条记录。 Ruby / Rails也是如此,它将使用1MB的内存。重复下一千条记录,将重用该内存。因此,您只使用前一个示例的一小部分RAM!