当我们要对数据做一些非常规的复杂运算时,通常要将数据装入内存。现在也有不少程序设计语言提供了内存数据集对象及基本的运算方法,可以较方便地实现这类运算。不过,如果对内存数据集的工作原理了解不够,就可能写出低效的代码。

我们看数据集的产生。比如要生成一个100行2列的数据集,第一列x为序号,第二列xx是第一列的平方。

第一种方法,先生成一个空数据集,再一行一行地追加数据进去。

A

B

1

=create(x,xx)

2

for 100

>A1.insert(0,A2,A2*A2)

第二种方法,直接产生相应行数的数据集。

A

B

1

=100.new(~:x,~*~:xx)

这两种方法产生的结果集相同,实质的循环次数和每次循环的计算内容看起来也相同,但执行效率却不一样,后者要比前者更快。

数据集在内存中会保存成一个连续的数组。动态追加的数据集,会导致这个数组长度不断地变长,原先为这个数组分配的空间也要扩大。而内存分配不是一件很简单的事情,已经分配好的空间的后面内存很可能已经被占用而不能再继续扩大,只能重新分配一块更大的空间,然后将原空间内的数据复制过来。寻找空间和复制数据都要占用CPU时间,常常比运算本身的消耗都大。一般情况下,分配内存时会多预留一些空间来应付可能的增长,这样不致于每次追加都导致重新内存分配,但也不可能预留太多而浪费内存,如果追加次数过多,仍然还会有不少时间消耗到内存分配上。而如果事先知道数据集行数一次性创建出来后,则只需要在开始做一次内存分配即可。

动态追加的数据集虽然使用起来更灵活,但性能却赶不上静态数据集,在关注性能时要习惯性地避免。


其实,用这个例子来对比并不很恰当,因为有100.new(~:x,~*~:xx)这样的简单写法时,很少人会采用动态追加的数据集了,这里用这个例子主要是为了突出关键差异。而实际应用中会有不少情况下很难用一句话写出数据集生成,程序员就可能习惯性地采用动态追加的数据集了。

举一个更恰当的例子,我们想生成一个20行2列的Fibonacci数据集,第一列key为行号,即1,2,3,…;第二列value为值。Fibonacci数列的规则是:第1、第2行取值为1,从第3行起,取值为前两行之和。这个运算需要一步步实现,使用动态数据集就是很自然的想法了:

A

B

1

=create(key,value)

2

>a=0

>b=1

3

for 20

>A1.insert(0,A3,b)

4

>b=a+b,a=b-a

不过,使用静态数据集的性能更好,即使计算本身仍然需要一步步实现,但数据集可以一次性产生:

A

B

1

=20.new(0:key,0:value)

2

>a=0

>b=1

3

for A1

>A3.key=#A3,A3.value=b

4

>b=a+b,a=b-a

先生成一个都填满0的数据集(随便别的什么数也可以),然后再用循环把正确的值填进去。实质计算量仍然一样,但避免了动态分配。


除了行方向动态追加外,还有列方向的问题,即在数据集上增加新的列。

列追加比行追加要更为复杂。内存数据集中的一行是一条记录,物理上也是一个数组。因为数据结构很少改变,大多数内存数据集不会在生成这个数组时预留空间,否则内存浪费就太多了(每一行都有)。这时候每次追加列时都会发生前面说的重新分配空间,而且要针对每一行记录进行,再将原记录数据抄过来,这个动作的时间成本经常远远超过追加的那个列本身的计算。

内存数据集一般都有提供追加列的功能,这会带来方便性,但在关注性能时却要慎用。能不用则不用,一定需要时,也是如上所述,最好是一次性把需要追加的列都加上,而不要一遍遍地追加。

比如我们想在第一个例子中的数据集上再追加两个列y=x+xx和yy=y*y。看起来较自然的两步写法:

A

B

3

=A1.derive(x+xx:y)

=A3.derive(y*y:yy)

一次性产生列的写法:

A

B

3

=A1.derive(x+xx:y,0:yy)

>A3.run(yy=y*y)

相比之下,后者的性能要更好。


类似技巧还可以用在从数据库中取出的数据集上。

比如要从数据表T中取出字段month和amount并按month排序,然后追加一列计算amount的累计值。先读出再追加列的写法:

A

B

1

=db.query(“select month,amount from T order by month)

2

=A1.derive(0:acc)

>a=0

3

for A1

>A3.acc=(a=a+A3.amount)

用SQL语句先把列生成好的写法:

A

B

1

=db.query(“select month,amount,0 as acc from T order by month)

>a=0

2

for A1

>A2.acc=(a=a+A2.amount)

对于关注性能的程序员,后一种写法会成为习惯。

原文发布时间为:2018-12-4

本文作者:蒋步星

本文来自云栖社区合作伙伴“ 数据蒋堂”,了解相关信息可以关注“shujujiangtang”微信公众号

内存数据集产生的隐性成本相关推荐

  1. 数据蒋堂 | 内存数据集产生的隐性成本

    作者:蒋步星 来源:数据蒋堂 本文共1500字,建议阅读7分钟. 本文带你了解内存数据集的工作原理. 当我们要对数据做一些非常规的复杂运算时,通常要将数据装入内存.现在也有不少程序设计语言提供了内存数 ...

  2. 云备份的5个隐性成本

    如今,许多组织已经认识到,采用云计算用于存储备份的副本来长期保存和灾难恢复是一个卓越的解决方案.多年来,企业依靠磁带或其他机械硬盘等存储介质满足"3规则"的最佳实践,也被称为3-2 ...

  3. Netflix推出Hollow,处理内存数据集的Java库

    Netflix最近推出了Hollow,一款Java库和工具包,旨在有效缓存不属于"大数据"的数据集.这些数据集可能是电子商务和搜索引擎的元数据,或者是Netflix电影和电视节目的 ...

  4. 闲谈隐性成本(太多人的思维盲区)

    那个,最近开始测试不同标题的反馈,写了这么多,没有爆发的文章,感觉好失败,如果您觉得标题不是很友好,看内容吧,还是能保持一贯风格的. 几年前没创业的时候,总是好奇为什么有些当老板的连自己赔了赚了都不知 ...

  5. 思腾合力-SCM集群 通过ssh上传大内存数据集至集群文件系统内

    相关链接: 思腾合力-SCM集群 上传镜像步骤 思腾合力-SCM集群 下载镜像步骤 思腾合力-SCM集群 通过ssh上传大内存数据集至集群文件系统内 思腾合力-SCM集群 通过ssh下载大内存数据集至 ...

  6. 再论信息化的隐性成本

    今天看到这一篇文章,是关于信息化的隐性成本的话题,觉的有些道理,但其实细看,更多地发现是站在软件商的角度来说这个问题的,在销售萌芽阶段.选型阶段.招标阶段,这些成本是必须的,而且这些所有的环节都将是软 ...

  7. 【译】探索 Kotlin 的隐性成本(第三部分)

    本文讲的是[译]探索 Kotlin 的隐性成本(第三部分), 原文地址:Exploring Kotlin's hidden costs - Part 3 原文作者:Christophe B. 译文出自 ...

  8. 隐性解析_开发移动应用程序的隐性成本

    隐性解析 More and more companies are realizing just how valuable a mobile application can be for their b ...

  9. 新的网络研讨会:如何避免持续交付的隐性成本

    现在该解决CI / CD工具链中缺失的环节了 不断变化,就会带来不断的风险. CI / CD计划的默默杀手its也是其最大的优势,当同一过程中推动发布向前发展的主要组成部分仍然过时而落伍时,其移动速度 ...

最新文章

  1. 饥荒海难机器人怎么用_饥荒海难机器人作用详解 机器人有什么用
  2. NodeJS学习笔记(四) events,util模块
  3. 结构(struct)
  4. 【BZOJ】1076 [SCOI2008]奖励关 期望DP+状压DP
  5. 轮播插件swiper.js?
  6. [转载] Java中Scanner用法总结
  7. 计算机控制lc72131,锁相环频率合成器—LC72131.PDF
  8. 苹果iPod设计及商业操作内幕
  9. 美联储加息已成“政治正确” 美元涨势难以阻挡?
  10. 用摄动法证明fibs的一个公式(继续变形)
  11. matlab drtoolbox 使用,MATLAB数据降维工具箱drtoolbox介绍
  12. x64位游戏call代码测试注入器
  13. 尾注参考文献之后添加附录致谢解决办法
  14. bugku misc 11-15 解题报告
  15. 最强大脑王昱珩,一个近乎完美的男人
  16. 两步解决XMind发生了错误,请参阅日志文件
  17. 2022重装Win7系统(64位)提示Windows update无法搜索新更新错误代码80072EFE
  18. java dubbo协议_Dubbo同时支持多种协议(以dubbo和rest为例)
  19. 【SQL注入技巧拓展】————4、高级SQL注入:混淆和绕过
  20. matlab算sma,[转载]通达信公式SMA函数计算方式的问题

热门文章

  1. Linux常用命令之yum
  2. mysql c++ 存数组,c++读取数据文件到数组的实例
  3. python一年一度的校园好歌声_歌声满校园
  4. 拉普拉斯算子_图机器学习图拉普拉斯算子的离散正则性,141页ppt,Discrete regularity graph Laplacians...
  5. 我狂揽16个offer:面试常问的这些问题你准备了吗?
  6. mysql 5乱码_MySQL 5.x乱码问题解决
  7. python commands执行不连续_[Python] 利用commands模块执行Linux shell命令
  8. string返回第n个字符_Programming in Lualua学习第13期 Lua字符串库
  9. 电脑主页面上的计算机没了,电脑界面上的internet explorer 没有了
  10. bio linux 创建_Linux设备驱动--块设备之概念和框架以及相关结构体