首頁 / 電子資訊 / 電路圖

內存比較小的時候碰到大量數據應該如何解決

  當你寫了一個處理數據的軟件,它可能在小樣本文件上運行地很好,但一旦加載大量真實數據後,這個軟件就會崩潰。   问题在于你没有足够的内存——如果你有 16GB 的 RAM ,你就无法一次载入 100GB 大小的文件。

  當你寫了一個處理數據的軟件,它可能在小樣本文件上運行地很好,但一旦加載大量真實數據後,這個軟件就會崩潰。

  问题在于你没有足够的内存——如果你有 16GB 的 RAM ,你就无法一次载入 100GB 大小的文件。载入这么大的文件时,操作系统在某个时刻就会耗尽内存,不能分配存儲單元,你的程序也就會崩潰。

  所以,你該怎樣防止這類情況發生?你可以啓動一個大數據集群——你所需要做的是:

  搞到一個計算機集群。

  花一周時間搭建這個集群。

  大部分情况下,你需要学习一套全新的 API,重写你所有的代码。

  這個代價可能很昂貴,會令人沮喪;幸運的是,大部分情況下,我們不必這樣做。

  你需要一个简单而容易的解决方案:在单机上处理你的数据,最小化环境搭建开销,尽可能利用你正在使用的代码库。实际上,大部分情况你都可以做到这样,只要使用一些方法即可,有时候这些方法被称为“核外计算”(out-of-core computation)。

  本文將介紹如下內容:

  你究竟为什么需要 RAM。

  處理無法放入內存的數據最簡單的方法:花些錢。

  處理大量數據的三種基本軟件方法:壓縮、分塊、索引。

  之后的文章将会展示如何把这些方法应用到诸如 NumPy 和 Pandas 这样的库中。

  1你究竟为什么需要 RAM?

  在我们开始解释解决方案前,我们要弄清楚该问题是如何产生的。我们的計算機内存(RAM)能让你读写数据,但是你的硬盘也可以读写数据——那为什么計算機还需要 RAM 呢?硬盘比 RAM 更便宜,所以它通常大到能够容纳下你的所有数据,那为什么你的代码不能直接从硬盘读写数据呢?

  理论上讲,这也行得通的。但是,即使是最现代化且速度很快的 SSD 硬盘也比 RAM 慢太多:

  从 SSD 上读取数据: 大约 1.6 万纳秒

  从 RAM 上读取数据: 大于 100 纳秒

  如果你想要实现快速计算,数据就只能放在 RAM 中,否则你的代码运行时就会慢上 150 倍。

  2资金方面的解决方案:购买更多的 RAM

  没有足够 RAM 时的最简单解决方案就是花钱来解决。你要么购买一台計算機,或者租一台云端的虚拟机(VM:Virtual Machine,这会比大多数笔记本电脑贵得多)。2019 年 11 月,我稍微调研了一下,在价格方面做了一些比较,发现你可以这样:

  购买 一台 Thinkpad M720 Tower,它有 6 个核和 64GB RAM,价格是 1074 美金。

  租用 一台云端的 VM,它有 64 个核和 432GB RAM,价格是每小时 3.62 美金。

  這只是我稍微調研後發現的數字,再繼續調研下去,你會發現更好的方案。

  如果花钱购买硬件可以把你的数据读入 RAM,这通常就会是一个最经济的解决方案:毕竟你的时间相当宝贵。但是,有时候,这还不够解决这个问题。

  例如,如果你要運行許多數據處理任務,在一段時期內,雲計算可能是一個自然能想到的解決方案,但也是一個昂貴的解決方案。曾經在一個工作中,我的軟件項目需要的計算開銷幾乎快用完了我們産品所有的預期收入,包括支付我薪水所需的至關重要的那部分收入。

  如果购买 / 租用更多的 RAM 不足以满足需求或者根本行不通时,下一步就应该考虑如何通过修改软件来减少内存使用了。

  3技巧 #1:压缩

  壓縮意味著用一種不同的表達形式表示你的數據,這種形式能占用更少內存。有兩種方式來壓縮:

  无损压缩: 存儲的数据包含的信息和原始数据包含的信息完全相同。

  有损压缩: 存儲的数据丢失了一些原始数据里的细节信息,但是这种信息丢失理想情况下不会对计算结果造成什么影响。

  我想说明的是,我不是在谈论使用 ZIP 或者 gzip 工具来压缩文件,因为这些工具通常是对硬盘上的文件进行压缩的。为了处理 ZIP 压缩过的文件,你通常需要把这个文件载入内存中再进行解压缩为原始文件大小,所以这其实对内存节省没有什么帮助。

  你需要的是內存中的數據壓縮表示形式。

  例如,比如說你的數據有兩個值,一共也只會有兩個值:“AVAILABLE”(代表可能取到的值)和“UNAVAILABLE”(代表不可能取到的值)。我们可以不必将其存为 10 个或更多字节的字符串,你可以将其存为一个布尔值,用 True 或者 False 表示,这样你就可以只用 1 个字节来表示了。你甚至可以继续压缩至 1 位来表示布尔值,这样就继续压缩到了 1 个字节时的 1/8 大小。

  4技巧 #2:分块,每次只加载所有数据里的某一块

  當你需要處理所有數據,而又無需把所有數據同時載入內存時,分塊是很有用的。你可以把數據按塊載入內存,每次計算一塊的數據(或者正如我們要在今後一篇文章裏想討論的,可以多塊並行處理)。

  例如,比如說,你想搜索一本書裏的最長單詞。你可以一次性將所有數據載入內存:

  largest_word = “” for word in book.get_text.split: if len(word) 》 len(largest_word):largest_word = word

  但是在我們的例子中,這本書太大而不能完全載入內存,這時候你就可以一頁一頁地載入這本書。

  largest_word = “” for page in book.iterpages: for word in page.get_text.split: if len(word) 》 len(largest_word): largest_word = word

  這樣你使用的內存就大大減少了,因爲你一次只需要把這本書的一頁載入內存,而最後得到的結果仍然是正確的。

  5技巧 #3:当你需要数据的一个子集时,索引会很有用

  當你需要數據的一個子集時,索引會很有用,使用索引你可以在不同時刻加載數據的不同子集。

  你也可以用分塊解決這個問題:每次加載所有的數據,過濾掉你不想要的數據。但這會很慢,因爲你加載了很多不相關的數據。

  如果你只需要部分數據,不要使用分塊,最好使用索引,它可以告訴你到哪裏能找出你關心的那部分數據。

  想象一下,你只想閱讀書本中關于土豚的章節。如果你運用分塊技術,你得載入整本書,一頁一頁的載入,每頁地搜尋土豚——但這要花很長時間才能完成。

  或者说,你可以直接阅读这本书的末尾部分,也就是书本的索引部分,然后找到“土豚”的索引项。它可能会告诉你在第 7、19 页以及 120-123 页可以读到相关内容。所以,现在你可以只读那几页,这样就快多了。

  這樣很有效,因爲索引比整本書占用的空間要小很多,所以把索引載入內存找出相關內容所在就會更容易。

  6最簡單的索引技巧

  最簡單也最常用的實現索引的方法就是在目錄裏給文件恰當命名:

  mydata/ 2019-Jan.csv 2019-Feb.csv 2019-Mar.csv 2019-Apr.csv 。..

  如果你想要 2019 年 3 月数据,你就只需要加载 2019-Mar.csv 这个文件——而不用加载 2 月、7 月或者其他任何月份的数据。

  7下一步:應用這些技巧

  RAM 不够用,最简单的解决方法就是花钱买更多的 RAM。但是,如果这个方案无法实现或者仍然不够用时,你就需要使用压缩、分块或者索引来解决。

  这些方法也出现在其他许多不同的软件包和工具中。即使是大數據系统也是建立在这些方法之上的:例如使用多个計算機来处理分块数据。

  在接下来的文章里,我会给你展示如何使用具体的库和工具(NumPy、Pandas,或者用 ZIP 工具压缩文件)来应用这些方法。如果在我写完这些文章时,你就想阅读到它们,请在下方表格里注册我的通讯简报(newsletter)。

唯樣商城(www.oneyac.com)是本土元器件目錄分銷商,采用“小批量、現貨、樣品”銷售模式,致力于滿足客戶多型號、高質量、快

速交付的采購需求。唯樣自建高效智能倉儲,擁有自營庫存超70,000種,提供一站式正品現貨采購、個性化解決方案、選項替代等多元化服務。

(本文來源網友上傳,如有侵權,可聯系管理員刪除)

本文由oneyac轉載自發燒友,原文標題爲:,本站所有轉載文章系出于傳遞更多信息之目的,且明確注明來源,不希望被轉載的媒體或個人可與我們聯系,我們將立即進行刪除處理。

相關文章