MATLAB中的“内存不足”?使用此技巧可轻松将内存使用量减半

MATLAB中的“内存不足”?使用此技巧可轻松将内存使用量减半

我将演示如何简单地更改数字数据的精度可以将内存使用量减少一半甚至更多

Photo by 拥有摄影 on 不飞溅

H 您是否曾经在 MATLAB 中遇到内存问题并上网查找?

Google Search result for what to do if you run out of memory.

事实证明,#7 在许多情况下是最简单的解决方案,最多可以减少 90% 的内存使用。此方法附带 额外的好处是,如果您保存变量,它们还将占用更少的硬盘空间并更快地加载 .

让我们深入了解如何减少内存使用(这些概念适用于其他编程环境,但我将专注于 MATLAB):

这篇文章中讨论的关键命令:

**谁是** ******单身的** ******双倍的** ******整数16** ******格式**

当涉及到数值数据时,您可以使用指定类型 单身的 或者 双倍的 但人们几乎从不这样做!这对您的数据意味着什么?让我们看一些随机的例子:

 我的数据 = 兰德(1000,1000); % 不要省略这个分号!  
 谁的我的数据

你会看到一个表格,上面写着你的变量 我的数据 字节值等于:8 000 000。即 8 兆字节。储存在你的记忆中。

在字节旁边,它会说“双”。默认情况下,MATLAB 会创建一个非常浪费的双精度变量。尝试这个:

 我的数据=单(兰德(1000,1000)); % 不要省略这个分号!  
 谁的我的数据

从双人变成单身,我们会失去什么?

 mydata_double = rand(1000,1000);  
 我的数据单=单(我的数据双);  
 mean(mydata_double,'all') % 这里没有分号  
 意思是(mydata_single,'全部'

您会看到双精度变量的结果是“0.500049032047244”,而单精度变量的结果是“0.5000491”。如果 5,000,490 和 5,000,491 之间的差异会对您的数据产生重大影响,那么 不要转换为单身 .

我们可以用整数做得更好吗?

是的。有警告。如果您对 50% 感到满意,您可以在此处停止阅读。但是,如果您愿意加倍努力,请继续。仅当您使用 single 然后使用整数格式 int8 或 int16 测试结果时才应该这样做,并且您确认它们具有可比性。使用整数很复杂,但在某些情况下是值得的。

  • 警告 1: 数据应该已经是双精度格式的整数,或者可以舍入为整数而不会丢失太多信息(例如 1.001、2.0045 等),或者您应该准备好来回转换数据。

如果你不小心,要看看这个警告会如何伤害你——试试这个:

 我的数据 = 兰德(10,10);  
 我的数据 = int8(我的数据);  
 我的数据

❌ 你会得到一堆 0 和 1,因为你的数据已经四舍五入了。

我们怎样才能避免这种情况?您可以将每个数字乘以 10、100 或 1000,然后在必要时再减去。

 % 扩大数据规模并缩小规模  
 to_integer = @(x) x*1000  
 to_decimal = @(x) double(x)/1000 % 转换为整数  
 mydata = int16(to_integer(rand(10,10))); % 又翻倍!  
 我的数据 = to_decimal(我的数据);
  • 警告 2: 你的整数必须有一个你不会超过的最小值和最大值(如果你这样做,它将被四舍五入到那个值)。

如果您正在转换使用 整数16 这意味着 -2¹⁶ 到 2¹⁶,因此您可以存储 -65536 和 +65536 之间的值 - 或 -6.5536 和 +6.5536 之间的小数精度 - 或 -65.636 和 +65.636 之间。看看它是如何工作的?

一个的最大值是多少 你8 矩阵?滚动到底部以获得答案。

警告 3: 如果要对矩阵进行某些类型的处理,则需要转换为双精度或单精度。例如,您可以获取矩阵的均值或标准差,但不能使用 投资 例如,计算矩阵逆。

让我们看看每种数据的节省情况

我们将尝试假设我们的数据将小于 256,并且我们可以容忍丢失一些小数(您应该始终检查这是否适用于您的数据)。

 to_integer = @(x) (x*100)  
 to_decimal = @(x) ( double(x) /100 ) 我的数据 = 兰德(1000,1000); % 8 MB 双倍  
 mydata_to_integer = to_integer(mydata); % 仍然是 8 兆字节(双倍)  
 mydata_to_integer = single(mydata_to_integer); % 现在 4 兆字节 % 检查最小值和最大值是否在 -2^162^16 之间  
 [ min(mydata_to_integer,[],'all'),max(mydata_to_integer,[],'all') ]  
 mydata_to_integer = int16(mydata_to_integer); % 现在 2 兆字节 % 因为最大值是 100,我们可以下到 int8 mydata_to_integer = int8(mydata_to_integer); % 1 兆字节!

现在让我们尝试恢复我们的原始数据,并通过计算平均值来看看它有多准确:

 长格式  
 mean(mydata, 'all') % 原始数据  
 to_decimal(mean(mydata_to_integer,'all')) % 转换回来的数据

0.500068458752177 与 0.500070540000000。让我们也计算标准偏差。

 标准(我的数据,[],'全部')  
 标准(to_decimal(双(mydata_to_integer)),[],'全部'

0.288641641801215 与 0.288675051151625 - 我们可以忍受。

结论

为了节省内存(RAM 和硬盘存储),您应该使用 单(你的变量) .这是将内存使用量减半的最简单、最直接的方法。如果你想减少高达 90% 的内存使用,你应该仔细尝试 整数16 或者 你8 (它存储 -256 和 +256 之间的值,作为上述问题的答案)。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明

本文链接:https://www.qanswer.top/2890/30353108

posted @   哈哈哈来了啊啊啊  阅读(1838)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」
点击右上角即可分享
微信分享提示