[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[原创教程] [Perl]通过 pack 压缩运行时数组的体积,节省内存空间

本帖最后由 523066680 于 2019-1-28 18:23 编辑
  1. use Devel::Size qw/total_size/;
  2. our ($a, $b, $c) = ([], [], '');
  3. for my $idx ( 0 .. 2000000 )
  4. {
  5.     '1'; push @$a, [0.5,  0.6,  0.8];
  6.     '2'; push @$b, pack("fff", 0.5,  0.6,  0.8);
  7.     '3'; $c .= pack('f3', 0.5, 0.6, 0.8 );
  8. }
  9. grep { printf "%s %.2f MB\n", $_, total_size(${"$_"})/1024**2 } ('a','b','c');
  10. =result
  11. a 298.87 MB
  12. b 96.69 MB
  13. c 25.08 MB
  14. =cut
复制代码
Devel::Size 是一个外部模块,用于检测某个容器的体积。
假设有一堆三维点阵数据,需要一次载入数组,为了方便会选用二维数组,通过数组引用的形式将 [x y z] 打包起来。
但是实测中发现内存很容易就爆满,特别是最初为了方便而使用哈希 {'x'=>0.5, 'y'=>'0.6', 'z'=>'0.8'},千万个坐标点秒秒钟 out of memory。

如果改用 pack 将数据打包,以二进制而不是字符串表面形式,push @$b, pack("fff", 0.5,  0.6,  0.8); 可以将体积压缩到1/3 (针对此例)
而如果使用字符串“流”的形式进行打包 $c .= pack('f3', 0.5, 0.6, 0.8 ),可将占用缩减到原来的 1/10 不到。
内存又宽松起来了  

对 pack 过的二维数组进行排序

本帖最后由 523066680 于 2019-1-28 21:47 编辑

在使用 pack 打包数据的情况下对二维数组排序。(以前写过一个普通版本的,参考:http://www.bathome.net/viewthread.php?tid=45306

最初的方案是在 sort { } 内嵌函数中使用 unpack 释放数据逐项对比(每次都unpack会产生冗余消耗)。
但细想似乎不需要unpack,由于每一个字段都是对齐的,可以直接按字符串对比,操作上反而简单了:
  1. =info
  2.     使用 pack 压缩数组的内存占用空间
  3.     二维不定长数组排序测试
  4.     523066680/vicyang
  5. =cut
  6. STDOUT->autoflush(1);
  7. srand(23);
  8. my @arr;
  9. print "Stage1\n";
  10. for (1 .. 20) {
  11.     push @arr, pack("L*", reverse sort { $a <=> $b } map { int(rand(15)) } ( 1 .. rand(8)+2 ) );
  12. }
  13. print "Stage2\n";
  14. grep { print join(",", unpack "L*", $_ ),"\n" } reverse sort @arr;
复制代码
  1. 14,14,10,9,1
  2. 14,13,9,8,8,7,4,2,2
  3. 14,10,8
  4. 14,8,7,4,3,3,3,0,0
  5. 14,8,1
  6. 13,13,13,13,9,8,6,4
  7. 13,11,9,7,7,6,2,1
  8. 13,10,7,0
  9. 13,9,8,7,5,1,1,1,0
  10. 12,12,11,6,6,6,4,4,2
  11. 12,11,6
  12. 12,10,2,2,2,0
  13. 12,6
  14. 11,10,1,0
  15. 11,9,9,1,1,0
  16. 11,4,3
  17. 10,9,7,0
  18. 9,8,7,7,6,3,3,3,1
  19. 7,7,4,1
  20. 6,3
复制代码
(排序规则,以开头元素的数值优先排序,后面的其次,最后如果同列的数字都相等,按长度判定。)

TOP

返回列表