性能优化: HashMap SparseArray ArrayMap

2023-12-23 04:38

本文主要是介绍性能优化: HashMap SparseArray ArrayMap,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

参考:

HashMap & SparseArray & ArrayMap 简单说明

安卓性能优化—使用ArrayMap与SparseArray

简介:

ArrayMap与SparseArray都要比传统的HashMap 更有效率;但是当数据量达到千级以上的时候,ArrayMap与SparseArray都要比传统的HashMap 效率更低50%;

ArrayMap和SparseArray一样,也会对key使用二分法进行从小到大排序,区别是ArrayMap的key是hash值,

SparseArray应用场景:

public class SparseArray<E> implements Cloneable {private int[] mKeys;					//key为intprivate Object[] mValues;		//value为泛型private int mSize;//............
}

虽说SparseArray性能比較好,可是由于其加入、查找、删除数据都须要先进行一次【二分查找】。

所以在数据量大的情况下性能并不明显,将减少至少50%。

满足下面两个条件我们能够使用SparseArray取代HashMap:

数据量不大,最好在千级以内

key必须为int类型,这中情况下的HashMap能够用SparseArray取代:

HashMap<Integer, Object> map = new HashMap<>();
//用SparseArray取代:
SparseArray<Object> array = new SparseArray<>();

SparseArray有两个优点:

1.避免了自动装箱(auto-boxing),

2.数据结构不会依赖于外部对象映射。

我们知道HashMap 采用一种所谓的“Hash 算法”来决定每个元素的存储位置,存放的都是数组元素的引用,通过每个对象的hash值来映射对象。而SparseArray则是用数组数据结构来保存映射,然后通过折半查找来找到对象。但其实一般来说,SparseArray执行效率比HashMap要慢一点,因为查找需要折半查找,而添加删除则需要在数组中执行,而HashMap都是通过外部映射。但相对来说影响不大,最主要是SparseArray不需要开辟内存空间来额外存储外部映射,从而节省内存。

HashMap

使用有限一维拉链数组存储结构,鉴于所用Entry结构{key, value, nextExtry},Key的hash值用于取余获得所属的数组行下标,通过链表方式顺序存放所有余数相同的各个Entry。该数组的每个存储单元被称为“桶”。

取值时依据hash定位到行,再遍历链表定位key对应的Entry对象,并通过此方式解决哈希冲突问题。

当 Entry总数据量 > 数组Length(桶容量) * 0.75默认加载因子时,数组将扩容至原数组2倍,并重新计算排布旧数据,重建数据结构,此步骤非常消耗性能,最佳方式是初始化HashMap为接近目标容量的2次幂大小,减少扩容次数。

桶容量设置得太高会导致内存浪费,而当数据量达到千万级别时容易产生大量冲突,导致冲突链表过长,影响性能。

SparseArray稀疏数组

Android框架内的优化型存储结构类,在key为整型数值类型时可考虑替代HashMap提供更有效的空间利用率。

内部通过两个平行数组方式分别(同步)存储key与value,key限定为int或long类型,节省内存,避免装箱拆箱。

采用二分法进行插入和查找,存储按大小排序,大数据集下数据插入速度慢,但查找性能高,在千级数据量内可取代HashMap。

SparseArray 的 key为int
LongSparseArray 的 key为long

 public class LongSparseArray<E> implements Cloneable { private long[] mKeys;					//key为longprivate Object[] mValues;			//value为泛型private int mSize;//............
}

ArrayMap

Android框架内的优化型存储结构类。

类似于SparseArray使用两个平行数组分别(同步)存储key与value,模拟Map使用方式,Key类型不限,同样采用二分法进行插入、查找。

LongSparseArray 和SparseArray的二分查找工具类:

class ContainerHelpers {// This is Arrays.binarySearch(), but doesn't do any argument validation.static int binarySearch(int[] array, int size, int value) {int lo = 0;int hi = size - 1;while (lo <= hi) {final int mid = (lo + hi) >>> 1;final int midVal = array[mid];if (midVal < value) {lo = mid + 1;} else if (midVal > value) {hi = mid - 1;} else {return mid;  // value found}}return ~lo;  // value not present}static int binarySearch(long[] array, int size, long value) {int lo = 0;int hi = size - 1;while (lo <= hi) {final int mid = (lo + hi) >>> 1;final long midVal = array[mid];if (midVal < value) {lo = mid + 1;} else if (midVal > value) {hi = mid - 1;} else {return mid;  // value found}}return ~lo;  // value not present}
}

这篇关于性能优化: HashMap SparseArray ArrayMap的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/526736

相关文章

MyBatisPlus如何优化千万级数据的CRUD

《MyBatisPlus如何优化千万级数据的CRUD》最近负责的一个项目,数据库表量级破千万,每次执行CRUD都像走钢丝,稍有不慎就引起数据库报警,本文就结合这个项目的实战经验,聊聊MyBatisPl... 目录背景一、MyBATis Plus 简介二、千万级数据的挑战三、优化 CRUD 的关键策略1. 查

JVisualVM之Java性能监控与调优利器详解

《JVisualVM之Java性能监控与调优利器详解》本文将详细介绍JVisualVM的使用方法,并结合实际案例展示如何利用它进行性能调优,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全... 目录1. JVisualVM简介2. JVisualVM的安装与启动2.1 启动JVisualVM2

Java使用MethodHandle来替代反射,提高性能问题

《Java使用MethodHandle来替代反射,提高性能问题》:本文主要介绍Java使用MethodHandle来替代反射,提高性能问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑... 目录一、认识MethodHandle1、简介2、使用方式3、与反射的区别二、示例1、基本使用2、(重要)

SpringBoot中HTTP连接池的配置与优化

《SpringBoot中HTTP连接池的配置与优化》这篇文章主要为大家详细介绍了SpringBoot中HTTP连接池的配置与优化的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一... 目录一、HTTP连接池的核心价值二、Spring Boot集成方案方案1:Apache HttpCl

PyTorch高级特性与性能优化方式

《PyTorch高级特性与性能优化方式》:本文主要介绍PyTorch高级特性与性能优化方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、自动化机制1.自动微分机制2.动态计算图二、性能优化1.内存管理2.GPU加速3.多GPU训练三、分布式训练1.分布式数据

MySQL中like模糊查询的优化方案

《MySQL中like模糊查询的优化方案》在MySQL中,like模糊查询是一种常用的查询方式,但在某些情况下可能会导致性能问题,本文将介绍八种优化MySQL中like模糊查询的方法,需要的朋友可以参... 目录1. 避免以通配符开头的查询2. 使用全文索引(Full-text Index)3. 使用前缀索

C#实现高性能Excel百万数据导出优化实战指南

《C#实现高性能Excel百万数据导出优化实战指南》在日常工作中,Excel数据导出是一个常见的需求,然而,当数据量较大时,性能和内存问题往往会成为限制导出效率的瓶颈,下面我们看看C#如何结合EPPl... 目录一、技术方案核心对比二、各方案选型建议三、性能对比数据四、核心代码实现1. MiniExcel

Java遍历HashMap的6种常见方式

《Java遍历HashMap的6种常见方式》这篇文章主要给大家介绍了关于Java遍历HashMap的6种常见方式,方法包括使用keySet()、entrySet()、forEach()、迭代器以及分别... 目录1,使用 keySet() 遍历键,再通过键获取值2,使用 entrySet() 遍历键值对3,

Java的"伪泛型"变"真泛型"后对性能的影响

《Java的伪泛型变真泛型后对性能的影响》泛型擦除本质上就是擦除与泛型相关的一切信息,例如参数化类型、类型变量等,Javac还将在需要时进行类型检查及强制类型转换,甚至在必要时会合成桥方法,这篇文章主... 目录1、真假泛型2、性能影响泛型存在于Java源代码中,在编译为字节码文件之前都会进行泛型擦除(ty

Golang HashMap实现原理解析

《GolangHashMap实现原理解析》HashMap是一种基于哈希表实现的键值对存储结构,它通过哈希函数将键映射到数组的索引位置,支持高效的插入、查找和删除操作,:本文主要介绍GolangH... 目录HashMap是一种基于哈希表实现的键值对存储结构,它通过哈希函数将键映射到数组的索引位置,支持