如何写成高性能的代码(三):巧用稀疏矩阵节省内存占用

如何,写成,高性能,代码,巧用,稀疏,矩阵,节省,内存,占用 · 浏览次数 : 223

小编点评

**稀疏矩阵** 稀疏矩阵是一种存储方式,它使用多个数组存储矩阵中的元素,以减少内存使用。稀疏矩阵通常用于存储稀疏矩阵,即矩阵中大多数元素为 0。 **稀疏矩阵的优点:** * 降低内存使用 * 提高搜索效率 * 减少内存访问时间 **稀疏矩阵的缺点:** * 需要使用多个数组存储元素 * 存储效率可能比稠密矩阵低 * 搜索效率可能低 **稀疏矩阵的存储方式:** 稀疏矩阵使用以下三种数组来存储元素: * **行索引数组**:存储每个行在矩阵中的索引 * **列偏移数组**:存储每个列在矩阵中的偏移值 * **值数组**:存储每个元素的值 **稀疏矩阵的复杂度:** * **空间复杂度:O(N2)**:其中 N 是矩阵的行数或列数 * **插入:O(1)** * **删除:O(1)** * **搜索:O(N)** * **访问:O(1)** **稀疏矩阵的应用:** 稀疏矩阵是一种非常有效的存储方法,它可以用于存储稀疏矩阵。这种方法可以用来优化存储性能,提高搜索效率,以及减少内存使用。 **稀疏矩阵的优点:** * 降低内存使用 * 提高搜索效率 * 减少内存访问时间 **稀疏矩阵的缺点:** * 需要使用多个数组存储元素 * 存储效率可能比稠密矩阵低 * 搜索效率可能低

正文

稀疏矩阵的概念

一个m×n的矩阵是一个由m行n列元素排列成的矩形阵列。矩阵里的元素可以是数字、符号及其他的类型的元素。

一般来说,在矩阵中,若数值为0的元素数目远远多于非0元素的数目,并且非0元素分布没有规律时,则称该矩阵为稀疏矩阵;与之相反,若非0元素数目占大多数时,则称该矩阵为稠密矩阵。定义非零元素的总数比上矩阵所有元素的总数为矩阵的稠密度。,下面的矩阵就是一个典型的稀疏矩阵。

我们日常使用的电子表格也是一个典型的稀疏矩阵场景,电子表格(SpreadJS, Excel,Google Sheet等等),整体看起来像一个table表格。,

其中列名称依次为A, B, C … …, 行名称依次为1, 2, 3 … …

举例一个比较极端的场景,在A1ZZ2000单元格分别赋值,这样我们就需要一个2000行,26*26+26=702列的矩阵来表示它,这个矩阵是一个明显的稀疏矩阵。

稀疏矩阵的存储方式及优化

直接存储为二维矩阵

直接使用二维矩阵会简单直接地存储整个电子表格,这样你不必每次都创建或删除一段内存。
但这是一种非常暴力的存储值的方法,这种方式下会消耗大量内容来存储毫无内容的单元格。
简单的来看一下它的复杂度:

  • 占用空间O(N2)
  • 插入数据需要破坏矩阵.
  • 删除数据需要破坏矩阵.
  • 搜索数据O(N2)
  • 访问数据O(1)

N是假设行和列具有相同长度并形成正方形矩阵的行/列数。

通过键值对(Map, Dictionary)优化

在这种方法中,只有在单元格有值时,我们才将单元格的值和位置存储在一起,使用HashMap或者Dictionary这些数据结构可以很容易的做到.。

下图我们可以看到,键值对中分别存储了单元格位置和单元格值。

来看一下它的复杂度:

  • 空间O(N)
  • 插入O(1)
  • 删除O(1)
  • 搜索O(N)
  • 访问O(1)

N为所记录的条目数。

通过稀疏矩阵存储方式优化

在稀疏矩阵中,我们可以使用三个不同的数组来存储行索引、列偏移、和其中的值,而不是直接在二维矩阵中存储值。以这种方式按列压缩稀疏矩阵

存储的三个数组:

  1.  =>单元格中的值。
  2. 行索引=>单元格的行索引。
  3. 列偏移=>这里每个索引都代表列,并且该数组将行开始的索引值存储在 Row 数组中。

稀疏矩阵具体的插入,、删除,、搜索,、访问的代码,大家可以自己来搜索,这方面的资料网上有很多。,这里不一一列举。

和上面一样,来看看这种方式的复杂度:

  • 空间O(N)
  • 插入O(N)
  • 删除O(N)
  • 搜索O(N)
  • 访问O(1)

相较于传统的数组存储或是键值对存储,稀疏矩阵存储构建了基于行索引为 Key 的数据字典,在松散布局的表格数据中,稀疏矩阵只会对非空数据进行存储,而不需要对空数据开辟额外的内存空间。使用这种特殊的存储策略,使得数据片段化变得容易,可以随时框取整个数据层中的一片数据,进行序列化或反序列化。如果我们在项目开发中需要存储类似结构的数据,稀疏矩阵这种存储方式,无论从时间还是空间上都能大大的提成性能。

在葡萄城的 SpreadJS GcExcel 表格组件中,也巧妙的使用了稀疏矩阵这一特性,可以随时替换或恢复整个存储结构中的任何一个级别的节点,以改变引用的方式更高效的地解决表格数据回滚和恢复问题,而这一点也为葡萄城表格组件支持多人在线协同打下了一个良好的基础。

由于底层采用了稀疏矩阵来优化存储,SpreadJS在前端页面中,实现了100W级别数据秒级响应的能力:

纯前端百万级数据请求、加载、筛选和排序

点击此处可以在线体验:性能演示

同时,结合SpreadJS中使用的Canvas 绘制模型,双缓存画布渲染等专利技术,让SpreadJS的前端性能相比于同类产品遥遥领先。

更多纯前端表格在线demo示例 :https://demo.grapecity.com.cn/spreadjs/gc-sjs-samples/index.html

纯前端表格应用场景:https://www.grapecity.com.cn/developer/spreadjs#scenarios

移动端示例(可扫码体验):http://demo.grapecity.com.cn/spreadjs/mobilesample/

与如何写成高性能的代码(三):巧用稀疏矩阵节省内存占用相似的内容:

如何写成高性能的代码(三):巧用稀疏矩阵节省内存占用

稀疏矩阵的概念 一个m×n的矩阵是一个由m行n列元素排列成的矩形阵列。矩阵里的元素可以是数字、符号及其他的类型的元素。 一般来说,在矩阵中,若数值为0的元素数目远远多于非0元素的数目,并且非0元素分布没有规律时,则称该矩阵为稀疏矩阵;与之相反,若非0元素数目占大多数时,则称该矩阵为稠密矩阵。定义非零

程序员减少BUG的两个小妙招!

我们说衡量一个程序员水平的高低往往有很多因素,但有一个因素至关重要即代码质量。 如果程序员写的功能在测试阶段就被频繁打回,上线了之后,用户反馈这里有问题那里有问题,大家可以想像这样的程序员水平能高到哪里去,纯粹一个“挖坑”程序员无疑。 那有没有什么窍门能减少程序出bug的概率呢? 这里作者分享两个我自己总结的减少程序出bug的小窍门,希望对你有所帮助。

5.12 汇编语言:仿写While循环语句

循环语句(While)一种基本控制结构,它允许程序在条件为真的情况下重复执行一段代码块,直到条件为假为止。循环语句在处理需要重复执行的任务时非常有用,它可以让程序更加高效地处理大量数据或者重复性操作。一般来说,While循环由一个条件表达式、一个代码块组成。在每次循环迭代开始时,程序会首先检查条件表达式的值,如果为真,则执行代码块,然后再次检查条件表达式的值。只要条件表达式为真,循环就会一直继续执

如何用ReadWriteLock实现一个通用的缓存中心?

摘要:在并发场景中,Java SDK中提供了ReadWriteLock来满足读多写少的场景。 本文分享自华为云社区《【高并发】基于ReadWriteLock开了个一款高性能缓存》,作者:冰 河。 写在前面 在实际工作中,有一种非常普遍的并发场景:那就是读多写少的场景。在这种场景下,为了优化程序的性能

机器学习策略篇:详解如何改善你的模型的表现(Improving your model performance)

如何改善模型的表现 学过正交化,如何设立开发集和测试集,用人类水平错误率来估计贝叶斯错误率以及如何估计可避免偏差和方差。现在把它们全部组合起来写成一套指导方针,如何提高学习算法性能的指导方针。 所以想要让一个监督学习算法达到实用,基本上希望或者假设可以完成两件事情。首先,的算法对训练集的拟合很好,这

DevOps| 研发效能和PMO如何合作共赢?

项目经理(PMO)对于大组织、跨团队高效协同有着不可替代的作用。跳出组织架构的束缚,横向推动公司级别的大项目向前推进,跟进进展和拿到结果,PMO的小伙伴有着独特的优势。 我之前写过小团队如何高效协作的一篇文章《 高效能敏捷交付团队反思:特性团队(FeatureTeam)+Scrum》,还写过一篇关于

痞子衡嵌入式:盘点国内Cortex-M内核MCU厂商高主频产品(2023)

大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家介绍的是国内Cortex-M内核MCU厂商高主频产品。 在 2021 年初痞子衡写了篇 《盘点国内Cortex-M内核MCU厂商高性能产品》,搜罗了当时市面上主频不低于 96MHz 的 CM 核国产 MCU。如今过去了两年,痞子衡又一次梳理了国

[转帖]Jmeter学习笔记(二十三)——生成HTML性能报告

https://www.cnblogs.com/pachongshangdexuebi/p/11759316.html 有时候我们写性能报告的时候需要一些性能分布图,JMeter是可以生成HTML性能报告的。这篇博客,简单介绍下在利用jmeter进行性能测试时,是如何生成HTML的可视化测试报告的

EasyExcel处理Mysql百万数据的导入导出案例,秒级效率,拿来即用!

一、写在开头 今天终于更新新专栏 《EfficientFarm》 的第二篇博文啦,本文主要来记录一下对于EasyExcel的高效应用,包括对MySQL数据库百万级数据量的导入与导出操作,以及性能的优化(争取做到秒级性能!)。 二、如何做技术选型 其实在市面上我们有很多常用的excel操作依赖库,除了

MySQL如何快速获取binlog的开始时间和结束时间

之前写过一篇文章MySQL如何获取binlog的开始时间和结束时间[1],文章里面介绍了如何获取MySQL数据库二进制日志(binlog)的开始时间与结束时间的一些方法。实际应用当中,我们可能还会遇到效率/性能方面的问题。最近对这个问题做了一些研究,这里就介绍一下如何快速获取MySQL二进制日志(b