背景

数据结构是指带有结构特性的数据元素的集合。在数据结构中,数据之间通过一定的组织结构关联在一起,便于计算机存储和使用。从大类划分,数据结构可以分为线性结构和非线性结构,适用于不同的应用场景。

  • 线性结构:

线性结构作为最常用的数据结构,它的特点是单个数据之间存在一对一的线性关系。包含两种不同的存储结构:顺序存储结构和链式存储结构。顺序存储的线性表称为顺序表,顺序表中的存储元素是连续的。

(线性结构)

链式存储的线性表被叫做链表,链表中的存储元素不一定是连续的,元素节点中存放数据元素以及相邻元素的地址信息

线性结构常见的有:数组、队列、链表和栈。

  • 非线性结构:

除了线性结构,其他的数据结构均为非线性结构,特点是单个数据之间存在多个对应关系,常见的有:二维数组,多维数组,广义表,树结构,图结构

(常见的非线性结构)

稀疏数组(Sparse Array)

在各种各样的数据结构中,最基础、最常用的是数组。数组可以非常直观的表示数据在一维或多维空间中的关系,与现实中的情形更接近,所以被大多数程序员当做首选的数据结构,然而,在部分应用场景中使用数组存储数据时会出现各种各样的情况,这是就需要在数组的基础上,对数据结构进行优化,衍生出稀疏数组等新的数据结构。

以五子棋局为例,我们应该如何存储棋盘上的落子情况呢?

(使用二位数组存储五子棋盘)

如果使用一个二维数组对棋盘落子进行存储,当我们拿到一个棋盘类数据内容时,大部分内容都是没有意义的0,有意义数据并不相邻,很多空间被浪费。对于五子棋来说,这个问题可能不是很明显,但如果棋盘;足够大,被浪费的空间就会影响到软件的功能实现,此时引入稀疏数组(SparseArray)就具有了重要的意义。

稀疏数组将数组中的内容进行压缩,存储在一个更为精练的二维数组中,稀疏数组的本质其实就是用时间置换空间。

具体的处理的方法是:

  1. 该数组之中一共有几行几列进行记录
  2. 把相同元素内容忽略后,只记录具有不同内容单元的位置

稀疏数组的实现

节约存储空间显然是稀疏数组的一个优势,但是读取性能是否可以会比二维数组差很多?

为了讲清这个问题,我们可以先看一下Android中SparseArray的实现逻辑。SparseArray内部是通过两个数组来进行数据存储的。一个存储key,另外一个存储value。我们从源代码中能够看到key和value各自是用数组表示:

  private int[] mKeys;private Object[] mValues;

同时,SparseArray在存储和读取数据时候,使用的是二分查找法:

 public void put(int key, E value) {int i = ContainerHelpers.binarySearch(mKeys, mSize, key);...}public E get(int key, E valueIfKeyNotFound) {int i = ContainerHelpers.binarySearch(mKeys, mSize, key);...}

在put添加数据的时候,会使用二分查找法和之前的key比较当前我们添加的元素的key的大小,然后按照从小到大的顺序排列好。所以,SparseArray存储的元素都是按元素的key值从小到大排列好的。 而在获取数据的时候,也是使用二分查找法判断元素的位置,这样可以使数据的获取变得更加高效。所以,在key的数据量(可以理解为棋盘上去掉空白后的棋子数量)不大时,稀疏数组读取性能是有保障的。

典型应用场景

做开发的都知道,想让系统变快有个最简单的办法就是加内存。对于程序可以做大量的缓存来加速,即所谓"空间换时间"。但是在特定环境,程序可使用的内存是有限的。

在移动设备上,内存是个稀缺资源,例如iPhone 7的内存为2G,而最新款的iPhone 13也仅为4G。所以,稀疏数组这种"时间换空间"的技术最早被广泛应用在移动开发领域。

除了移动端,另一个内存紧缺的运行环境是浏览器。虽然没有明文规定,但在业界的共同认知里,浏览器会对单一线程进行内存限制,例如64位的chrome,每个tab页的内存消耗不允许超过4G。这个限制,在单页面应用还不成熟的十几年前,不会成为问题。因为,那时大家所关注的,还是如何提升后端的处理性能,前端只是一种静态的网页表达方式。

随着前端工程化的高速发展,各种前端工程脚手架日渐成熟,WebComponent标准被提上日程,企业开始由C/S向B/S应用转型。这就要求前端开发者,需要面对单页面处理复杂业务数据的挑战。前端程序从最开始设计以及整个开发过程中都需要考虑内存的使用情况,尽可能的降低内存占用,防止网页崩溃。以前端电子表格为例,我们通常需要为用户提供上百万个单元格(100列 x 1万行),但其中有数据的单元格可能只有几百个。为了减少数据模型占用的内存,我们最终的解决方式是将表格的数据存储方式由常规数组改成稀疏数组,内存占用可以降低到几十分之一,以确保浏览器内存不会被撑爆。

(稀疏矩阵存储策略)

不只是“时间换空间”;

相较于传统的链式存储或是数组存储,稀疏矩阵存储构建了基于索引Key的数据字典。在松散布局的表格数据中,稀疏矩阵只会对非空数据进行存储,而不需要对空数据开辟额外的内存空间。

使用这种特殊的存储策略,除了可以降低内存占用,还使得数据片段化变得容易,可以随时框取整个数据层中的一片数据,进行序列化或反序列化,而无需处理同一数据结构内的其他数据。

借用这样的特性,我们可以随时替换或恢复整个存储结构中的任何一个级别的节点,以改变引用的方式高效解决了表格数据回滚和恢复,而这一点也是电子表格支持在线协同的技术基础。

总结

本节为大家介绍了稀疏数组的基础知识,技术实现和应用场景,以前端电子表格为例,展示了这个技术在节约内存空间,实现回滚恢复等领域的优势。

在后续我们还会继续为大家介绍更多严肃和有趣的内容~

觉得不错点个赞再走吧~

转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具、解决方案和服务,赋能开发者。

【月光宝盒get√】用时间置换空间,聊聊稀疏数组的那些事儿相关推荐

  1. 坑系列 --- 时间和空间的平衡

    这是坑系列的最后一弹了,这篇文章非常长,希望你能看完,要是看完有很酣畅的感觉就最好了.这一篇的坑主要来说说架构中时间和空间的平衡吧,这里的时间指代比较广,可能是开发时间,但大部分指的是执行时间,也就是 ...

  2. FPGA之道(61)时空变换之时间换空间

    文章目录 前言 时空变换之时间换空间 逻辑合并 模块复用之提速复用原理 简单提速复用 复杂提速复用 一个简单的FIR滤波器 FIR滤波器的转置结构 多路FIR滤波需求初步分析 提速后的问题分析 FIR ...

  3. 后向重计算在OneFlow中的实现:以时间换空间,大幅降低显存占用

    撰文 | 赵露阳 2016年,陈天奇团队提出了亚线性内存优化相关的"gradient/activation checkpointing(后向重计算)"等技术[1],旨在降低深度学习 ...

  4. 【Day28 文献泛读】人类数字、时间和空间加工的关联性与独立性

    阅读文献: 陈亚林, & 刘昌. (2013). 人类数字.时间和空间加工的关联性与独立性. 科学通报, 58(25), 2622-2630. 文献链接:人类数字.时间和空间加工的关联性与独立 ...

  5. 时间、空间、对象 海量极速多维检索 - 阿里云RDS PostgreSQL最佳实践

    标签 PostgreSQL , 时间 , 空间 , 对象属性 , 多维度检索 , 海量 , 空间索引 , 数据分区 , 块级索引BRIN , 多级索引 , GIN倒排索引 , JSON索引 , 多列索 ...

  6. C++核心准则边译边学-P.9 不要浪费时间和空间

    P.9: Don't waste time or space(不要浪费时间和空间) Reason(原因) This is C++. 我们在用C++. 译者注:之所以选择C++而不是其他语言,就是希望使 ...

  7. 冬瓜哥对时间和空间的理解方式—时空参悟(下)

    时空参悟(下) 第四部分:空间和维度 抖动着前进 根据上述分析,如果用实验去观察一个物体的运动,会发现锯齿状的前进路径,"抖动着前进",每一步是一个波长,而不是一根纯粹的直线,但是 ...

  8. 虚拟存储器基本思想:以时间换空间

    虚拟存储器基本思想是以时间换空间,主要意思是:通过消耗一定的额外时间(缺页中断处理时间.等请求分页系统中独有操作的时间),来达到扩大内存的逻辑空间的目的,从而给用户提供超过内存大小的进程逻辑空间.

  9. 时间与空间之旅 解题报告

    时间与空间之旅 Time Limit:1000MS  Memory Limit:65536K Description 公元22XX年,宇宙里最普遍的交通工具是spaceship.Spaceship的出 ...

最新文章

  1. Java项目:宿舍寝室维修上报管理系统(java+SpringBoot+FreeMarker+Mysql)
  2. OpenCV小部件的姿势Pose of a widget
  3. win7安装matlab的问题,安装matlab7.0出现问题,我是win7+64位系统,求解
  4. java desktop mailto,mailto在Java?
  5. 笨方法“学习python笔记之变量及打印
  6. CSS3边框图片、边框阴影、文本阴影
  7. ssm mysql增删改查_SSM配置并实现简单的数据库增删改查操作
  8. 计算机应用在服务业的发展,饮食服务业计算机应用的现状与未来
  9. Unity Shader - shader forge - #pragma only_renderers 和 exclude_renderers - 导致像素全黑
  10. 手摸手。完成一个H5 抽奖功能
  11. 外贸SOHO具备的素质
  12. Linux svn up 遇到Conflict discovered in
  13. 重做raid后,重启无法进入系统
  14. Nodejs安装在D盘酱紫报错?
  15. python做一个网页多少钱_网站建设平台_ 网站建设多少钱_ _做一个企业网站需要多少钱_64岁的Python之父表示退休后太无聊 正式加入微软...
  16. 批量下载人像图片的技巧,POCO相册图片如何下载的方法
  17. Vista HTTPS 证书错误
  18. java多线程使用业务场景_Java多线程使用场景
  19. 由开发者的人品问题领略测试人员的人品问题
  20. 合宙ESP32S3 CameraWebServe 测试demo

热门文章

  1. 罗切斯特计算机官网,罗切斯特大学计算机
  2. Sun OS Classic Command
  3. 北邮2019软院考研经验分享
  4. 张驰咨询:为什么六西格玛项目完成后容易反弹?
  5. 海量数据:判断一棵树是否为另一棵树的子树
  6. 南京理工大学机械考研考情与难度、参考书及上岸前辈备考经验指导
  7. 迅雷7优化,删除组件,去广告,屏蔽上传,高速通道,下载
  8. Python面向对象练习(创建类计算正方形周长与面积)
  9. 003-Android-Activity和Intent习题
  10. python magic methods