Ruby on rails Ruby:批量加载对象如何提高内存使用率?

Ruby on rails Ruby:批量加载对象如何提高内存使用率?,ruby-on-rails,ruby,performance,Ruby On Rails,Ruby,Performance,我是自学成才的,不太清楚将对象加载拆分为循环中的单独部分所带来的术语或具体改进(如果有的话) 例如,我使用rails,最近遇到了一个问题,我一次加载了太多沉重的ActiveRecord对象,并在rails API中发现: find_in_batches的作用是将查询分为多个子集,这样就不用进行一个大查询,而是进行10个小查询,而不用一次加载这么多对象 例: 我的问题是,这样做到底有什么好处?从概念上讲,我理解一次加载较少允许在每个循环上释放内存(这是正确的吗??),但具体改进了什么?我相信这是内

我是自学成才的,不太清楚将对象加载拆分为循环中的单独部分所带来的术语或具体改进(如果有的话)

例如,我使用rails,最近遇到了一个问题,我一次加载了太多沉重的ActiveRecord对象,并在rails API中发现:

find_in_batches
的作用是将查询分为多个子集,这样就不用进行一个大查询,而是进行10个小查询,而不用一次加载这么多对象

例:

我的问题是,这样做到底有什么好处?从概念上讲,我理解一次加载较少允许在每个循环上释放内存(这是正确的吗??),但具体改进了什么?我相信这是内存消耗的峰值,但这是否转化为RAM/CPU使用率的提高(老实说,我不太确定RAM/CPU之间的区别是什么)?或者与垃圾收集或Ruby堆大小有关


只是想了解一下较低层次的细节。谢谢

假设您希望处理数据库中的100万条记录

首先,您的数据库需要加载一百万条记录并将其发送到Ruby应用程序。然后Rails需要解析这100万条记录(这将使用内存),然后生成100万条记录和一个大数组来包含all。这将使用大量的处理能力(CPU)和内存(RAM)来存储它们

假设每条记录占用1KB内存(这是一个任意数字)。那么100万将占用1GB的内存,我们甚至不计算数据库、传输和转换所使用的内存


现在,加载100万条记录,一批一千条。然后,数据库一次只加载和传输1000条记录。Ruby/Rails也是如此,它将使用1MB的内存。重复下千条记录,将重用该内存。因此,您只使用了前面示例中RAM的一小部分

假设您希望处理数据库中的100万条记录

首先,您的数据库需要加载一百万条记录并将其发送到Ruby应用程序。然后Rails需要解析这100万条记录(这将使用内存),然后生成100万条记录和一个大数组来包含all。这将使用大量的处理能力(CPU)和内存(RAM)来存储它们

假设每条记录占用1KB内存(这是一个任意数字)。那么100万将占用1GB的内存,我们甚至不计算数据库、传输和转换所使用的内存


现在,加载100万条记录,一批一千条。然后,数据库一次只加载和传输1000条记录。Ruby/Rails也是如此,它将使用1MB的内存。重复下千条记录,将重用该内存。因此,您只使用了前面示例中RAM的一小部分

RAM=内存;CPU=处理能力。这可以节省内存(RAM)。谢谢!那么CPU是如何节省的呢?CPU是通过提高算法的效率来节省的,从而最大限度地减少需要进行的计算量。有时,这是通过确保大型循环不会不必要地重新计算来实现的;并通过存储中间值。当然,有时必须通过在多个CPU之间分配负载(通过线程、作业队列、多个进程等)来增加而不是节省CPU,RAM=内存;CPU=处理能力。这可以节省内存(RAM)。谢谢!那么CPU是如何节省的呢?CPU是通过提高算法的效率来节省的,从而最大限度地减少需要进行的计算量。有时,这是通过确保大型循环不会不必要地重新计算来实现的;并通过存储中间值。当然,有时必须通过在多个CPU之间分配负载(通过线程、作业队列、多个进程等)来增加而不是节省CPU,谢谢!那么,每次迭代的内存是否被释放/垃圾回收/其他什么呢?它将被垃圾回收。分批运行肯定会使用比我描述的更多的内存,因为GC可能会在一些循环之后运行,但是在必要时可以回收内存,所以您永远不会耗尽内存。谢谢!那么,每次迭代的内存是否被释放/垃圾回收/其他什么呢?它将被垃圾回收。分批运行肯定会使用比我描述的更多的内存,因为GC可能会在一些循环之后运行,但是在必要时可以回收内存,所以您永远不会耗尽内存。
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