当前位置: 首页 > news >正文

Android性能优化—数据结构优化

优化数据结构是提高Android应用性能的重要一环。在Android开发中,ArrayList、LinkedList和HashMap等常用的数据结构的正确使用对APP性能的提升有着重大的影响。

一、ArrayList

ArrayList内部使用的是数组,默认大小10,当数组长度不足时,会进行扩容,扩容后的长度为原来的1.5倍。扩容实际上是新建一个长度为原数组1.5的新数组,然后遍历原数组,将数据一一赋值给新数组。

add(position,object) 给指定位置添加元素时,会将该元素及其下标后面的元素都往后移动一位,
最后将add的元素添加到position位置。

delete(position) 删除指定位置元素,删除该元素,并将该元素下标后面的元素都往前移动一位。

由于添加和删除指定位置的元素,其后面的元素需要移动,造成耗时,速度慢,在尾部添加和删除不需要移动,不受影响。

优缺点:

读取速度快,尾部添加和删除速度快,中途添加和删除速度慢。

使用场景:

1)ArrayList提供了常数时间复杂度的随机访问操作(get和set方法),因为它内部使用数组来存储元素,可以通过索引直接访问元素。

2)ArrayList对于在末尾添加或删除元素的操作具有较好的性能,时间复杂度为O(1)。当需要在集合的尾部频繁添加和删除元素时,可以使用ArrayList。

3)ArrayList对于在中间位置插入或删除元素的操作性能较差,因为需要移动后续元素来保持顺序。如果需要频繁在集合的中间位置进行插入或删除操作,LinkedList更适合。

4)在创建ArrayList时,如果能够预估元素数量,可以通过指定初始容量,避免频繁的扩容操作,提高性能。

数组特点:

存储区间是连续,且占用内存严重,空间复杂也很大,时间复杂为O(1)。

优点:是随机读取效率很高,原因数组是连续(随机访问性强,查找速度快)。

缺点:插入和删除数据效率低,因插入数据,这个位置后面的数据在内存中要往后移的,且大小固定不易动态扩展。

二、LinkList

双链表结构,添加和删除速度快;查询需要从头遍历所有节点,速度慢。不需要连续内存,不会导致内存浪费。

链表特点:

区间离散,占用内存宽松,空间复杂度小,时间复杂度O(N)。

优点:插入删除速度快,内存利用率高,没有大小固定,扩展灵活。

缺点:不能随机查找,每次都是从第一个开始遍历(查询效率低)。

使用场景:

1)需要频繁在集合的中间位置插入或删除元素;

2)不需要频繁随机访问元素;

3)需要高效的插入和删除操作而不关心空间开销,LinkedList在插入和删除操作上的性能优于ArrayList,但它需要额外的空间来存储链表节点的指针,因此在空间开销上相对较高。

三、HashMap

1.7及之前使用 数组+链表

1.7之后使用 数组+链表+红黑树

 

数组+链表:

HashMap数组默认长度16,加载因子默认0.75f,当数组中存储的元素 > 0.75*数组长度 时,需要扩容,将数组长度扩容为原来的2倍,以保证为2的整数次幂。

HashMap以key-value成对出现,一个key对应一个value;

put:key-value
通过key获取hash值,然后跟数组长度取模 == key-value存储在数组的下标;
然后将key、hash值、value、下一个节点,封装成一个节点,插到链表的头节点 -- 头插法

get:key
通过key获取hash值,然后跟数组长度取模 == key-value存储在数组的下标;
然后遍历数组下标元素--链表,通过判断节点的key值一致,返回对应的节点。

  

扩容:

由于扩容后数组长度不一致,导致按原数组长度计算的下标失效,所以在扩容后,需要将原HashMap保存元素遍历,按新的数组长度,重新计算数组下标,存储。该过程耗时,故尽量在使用HashMap时,评估实际数组的长度,在创建HashMap时指定其长度,避免出现扩容的情况。

优缺点:

数组的特点:查询效率高,插入,删除效率低。

链表的特点:查询效率低,插入删除效率高。

在HashMap底层使用数组+链表+红黑树的结构完美的解决了数组和链表的问题,使得查询和插入,删除的效率都很高。

当数组中存储的元素 > 0.75*数组长度时,需要扩容,导致HashMap至少有25%的空间浪费,无疑是使用了空间换时间的方式去提高效率。

四、SparseArray

Android为了解决HashMap存在的空间浪费问题,推出的新数据类型;采用双数组的方式+HashMap的思想+二分查找,解决HashMap浪费空间的同时,提高了效率。

  

缺点:SparseArray的key只能是int类型

SparseArray采用了延迟删除的机制,通过将删除KEY的Value设置DELETED,方便之后对该下标的存储进行复用;

使用二分查找,时间复杂度为O(LogN),如果没有查找到,那么取反返回左边界,再取反后,左边界即为应该插入的数组下标;

如果无法直接插入,则根据mGarbage标识(是否有潜在延迟删除的无效数据),进行数据清除,再通过System.arraycopy进行数组后移,将目标元素插入二分查找左边界对应的下标;

mSize小于等于keys.length,小于的部分为空数据或者是gc后前移的数据的原数据(也是无效数据),因此二分查找的右边界以mSize为准;

mSize包含了延迟删除后的元素个数;如果遇到频繁删除,不会触发gc机制,导致mSize 远大于有效数组长度,造成性能损耗;

mGarbage为true不一定有无效元素,因为可能被删除的元素恰好被新添加的元素覆盖;

  

使用场景:

key为整型;不需要频繁的删除;元素个数相对较少。

五、ArrayMap

实现了Map接口,并使用int[]数来存储key的hash值,数组的索引用作index,而使用Object[]数组来存储key<->value ,这还是比较新颖的 。

使用二分查找查找hash值在key数组中的位置,然后根据这个位置得到value数组中对应位置的元素。

和SparseArray类似,当数据有几百条时,性能会比HashMap低50%,因此ArrayMap适用于数据量很小的场景

ArrayMap和HashMap的区别:

1)ArrayMap的存在是为了解决HashMap占用内存大的问题,它内部使用了一个int数组用来存储元素的hashcode,使用了一个Object数组用来存储元素,两者根据索引对应形成key-value结构,这样就不用像HashMap那样需要额外的创建Entry对象来存储,减少了内存占用。但是在数据量比较大时,ArrayMap的性能就会远低于HashMap,因为 ArrayMap基于二分查找算法来查找元素的,并且数组的插入操作如果不是末尾的话需要挪动数组元素,效率较低。

2)而HashMap内部基于数组+单向链表+红黑树实现,也是key-value结构, 正如刚才提到的,HashMap每put一个元素都需要创建一个Entry来存放元素,导致它的内存占用会比较大,但是在大数据量的时候,因为HashMap中当出现冲突时,冲突的数据量大于8,就会从单向链表转换成红黑树,而红黑树的插入、删除、查找的时间复杂度为O(logn),相对于ArrayMap的数组而言在插入和删除操作上要快不少,所以数据量上百的情况下,使用HashMap会有更高的效率。

如何解决冲突问题:

在ArrayMap中,假设存在冲突的话,并不会像HashMap那样使用单向链表或红黑树来保留这些冲突的元素,而是全部key、value都存储到一个数组当中,然后查找的话通过二分查找进行,这也就是当数据量大时不宜用ArrayMap的原因了。

相关文章:

Android性能优化—数据结构优化

优化数据结构是提高Android应用性能的重要一环。在Android开发中&#xff0c;ArrayList、LinkedList和HashMap等常用的数据结构的正确使用对APP性能的提升有着重大的影响。 一、ArrayList ArrayList内部使用的是数组&#xff0c;默认大小10&#xff0c;当数组长度不足时&…...

STL模板——vector详解

一、vector对象的定义和初始化方式 vector 中的数据类型 T 可以代表任何数据类型&#xff0c;如 int、string、class、vector&#xff08;构建多维数组&#xff09; 等&#xff0c;就像一个可以放下任何东西的容器&#xff0c;因此 vector 也常被称作容器。字符串类型 string …...

国际顶级学术会议ISSTA召开,中山大学与微众银行联合发表区块链最新研究成果

美国当地时间7月17日&#xff0c;软件工程领域顶级会议ISSTA 2023在西雅图正式召开。ISSTA &#xff08;The 32nd ACM SIGSOFT International Symposium on Software Testing and Analysis &#xff09;是软件测试与分析方面最著名的国际会议之一&#xff0c;也是中国计算机学会…...

Android开发从0开始(图形与按钮)

Drawable: drawable是抽象类。包括图片&#xff0c;色块&#xff0c;画板&#xff0c;背景。 drawable-ldpi 存放低分辨率图片。drawable-hdpi 高分辨率。drawable-xxhdpi 超高分辨率。 Android:src”drawable/image” 即可使用 Shape: 形状图形。圆角&#xff0c;矩形等常见几…...

Git入门到精通——保姆级教程(涵盖GitHub、Gitee、GitLab)

文章目录 前言一、Git1.Git-概述1.1.Git-概述-版本控制介绍1.2.Git-概述-分布式版本控制VS集中式版本控制1.3.Git-概述-代码托管中心1.4.Git-概述-安装和客户端的使用 2.Git-命令(常用命令)2.1.Git-命令-设置用户签名2.2.Git-命令-初始化本地库2.3.Git-命令-查看本地库状态2.4.…...

题解 | #J.Permutation and Primes# 2023牛客暑期多校8

J.Permutation and Primes 构造 题目大意 给定一个正整数 n n n &#xff0c;构造一个 n n n 的排列&#xff0c;使得每对相邻元素的和或差的绝对值为一奇素数 解题思路 两个数的和或差是奇数&#xff0c;那么它们的奇偶性一定是不同的&#xff0c;因此所求排列中&#…...

用vim打开后中文乱码怎么办

Vim中打开文件乱码主要是文件编码问题。用户可以参考如下解决方法。 1、用vim打开.vimrc配置文件 vim ~/.vimrc**注意&#xff1a;**如果用户根目录下没有.vimrc文件就把/etc/vim/vimrc文件复制过来直接用 cp /etc/vim/vimrc ~/.vimrc2、在.vimrc中加入如下内容 set termen…...

自然语言处理: 第六章Transformer- 现代大模型的基石

理论基础 Transformer&#xff08;来自2017年google发表的Attention Is All You Need (arxiv.org) &#xff09;&#xff0c;接上面一篇attention之后&#xff0c;transformer是基于自注意力基础上引申出来的结构&#xff0c;其主要解决了seq2seq的两个问题: 考虑了原序列和目…...

01-Hadoop集群部署(普通用户)

Hadoop集群部署&#xff08;普通用户&#xff09; 环境准备 1&#xff09;准备3台客户机&#xff08;关闭防火墙、静态IP、主机名称&#xff09; 如果这一步已经配置过了&#xff0c;可以忽略 # 1 关闭防火墙 systemctl stop firewalld.service # 关闭当前防火墙 systemctl…...

DC电源模块关于的电路布局设计

BOSHIDA DC电源模块关于的电路布局设计 DC电源模块是现代电子设备中常用的电源模块之一&#xff0c;其功能是将市电或其他输入电源转换成定电压、定电流的直流电源输出&#xff0c;以满足电子设备的供电需求。电路布局的设计是DC电源模块的重要组成部分&#xff0c;它直接影响…...

MATLAB实现免疫优化算法(附上多个完整仿真源码)

免疫优化算法是一种基于免疫学原理的优化算法。该算法的基本思想是通过模拟人类免疫系统的功能&#xff0c;来寻找最优解。 MATLAB是一种专门用于数学计算和数据处理的软件工具&#xff0c;它具有强大的数学计算和数据分析能力&#xff0c;可以方便地实现各种优化算法。 本文…...

登录界面中图片验证码的生成和校验

一、用pillpw生成图片验证码 1、安装pillow pip install pip install pillow2、下载字体 比如&#xff1a;Monaco.ttf 3、实现生成验证码的方法 该方法返回一个img ,可以把这个img图片保存到内存中&#xff0c;也可以以文件形式保存到磁盘&#xff0c;还返回了验证码的文字…...

go的make使用

在 Go 语言中&#xff0c;make 是一个用于创建切片、映射&#xff08;map&#xff09;和通道&#xff08;channel&#xff09;的内建函数。它提供了一种初始化和分配内存的方式&#xff0c;用于创建具有特定长度和容量的数据结构。下面将详细介绍 make 函数的使用方法和各种情况…...

竞赛项目 深度学习实现语义分割算法系统 - 机器视觉

文章目录 1 前言2 概念介绍2.1 什么是图像语义分割 3 条件随机场的深度学习模型3\. 1 多尺度特征融合 4 语义分割开发过程4.1 建立4.2 下载CamVid数据集4.3 加载CamVid图像4.4 加载CamVid像素标签图像 5 PyTorch 实现语义分割5.1 数据集准备5.2 训练基准模型5.3 损失函数5.4 归…...

一元三次方程求解

一元三次方程求解 题目描述提示输入输出格式输入格式输出格式 输入输出样例输入样例输出样例 算法分析A C 代码 题目描述 有形如&#xff1a; a x 3 b x 2 c x d 0 ax^3bx^2c^xd0 ax3bx2cxd0一元三次方程。给出该方程中各项的系数 ( a a a&#xff0c; b b b&#xff0c;…...

基于java在线音乐网站设计与实现

在线音乐网站的设计与实现 摘 要 随着互联网趋势的到来&#xff0c;各行各业都在考虑利用互联网将自己推广出去&#xff0c;最好方式就是建立自己的互联网系统&#xff0c;并对其进行维护和管理。在现实运用中&#xff0c;应用软件的工作规则和开发步骤&#xff0c;采用SSM框架…...

Python爬虫如何更换ip防封

作为一名长期扎根在爬虫行业动态ip解决方案的技术员&#xff0c;我发现很多人常常在使用Python爬虫时遇到一个困扰&#xff0c;那就是如何更换IP地址。别担心&#xff0c;今天我就来教你如何在Python爬虫中更换IP&#xff0c;让你的爬虫不再受到IP封锁的困扰。废话不多说&#…...

涛思数据联合长虹佳华、阿里云 Marketplace 正式发布 TDengine Cloud

近日&#xff0c;涛思数据联合长虹佳华&#xff0c;正式在阿里云 Marketplace 发布全托管的时序数据云平台 TDengine Cloud&#xff0c;为用户提供更加丰富的订购渠道。目前用户可通过阿里云 Marketplace 轻松实现 TDengine Cloud 的订阅与部署&#xff0c;以最低的成本搭建最高…...

特殊符号的制作 台风 示例 使用第三方工具 Photoshop 地理信息系统空间分析实验教程 第三版

特殊符号的制作 首先这是一个含有字符的&#xff0c;使用arcgis自带的符号编辑器制作比较困难。所以我们准备采用Adobe Photoshop 来进行制作符号&#xff0c;然后直接导入符号的图片文件作为符号 我们打开ps&#xff0c;根据上面的图片的像素长宽比&#xff0c;设定合适的高度…...

IoTDB1.X windows运行失败问题的处理

在windows运行 IoTDB1.x时 会出现如图所示的问题 为什么会出现这样的问题&#xff1f;java没有安装还是未调用成功&#xff0c;我是JAVA8~11~17各种更换都未能解决问题&#xff0c;最后对其bat文件进行查看&#xff0c;发现在conf\datanode-env.bat、conf\confignode-env.bat这…...

51c自动驾驶~合集58

我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留&#xff0c;CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制&#xff08;CCA-Attention&#xff09;&#xff0c;…...

【OSG学习笔记】Day 18: 碰撞检测与物理交互

物理引擎&#xff08;Physics Engine&#xff09; 物理引擎 是一种通过计算机模拟物理规律&#xff08;如力学、碰撞、重力、流体动力学等&#xff09;的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互&#xff0c;广泛应用于 游戏开发、动画制作、虚…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器

——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的​​一体化测试平台​​&#xff0c;覆盖应用全生命周期测试需求&#xff0c;主要提供五大核心能力&#xff1a; ​​测试类型​​​​检测目标​​​​关键指标​​功能体验基…...

DAY 47

三、通道注意力 3.1 通道注意力的定义 # 新增&#xff1a;通道注意力模块&#xff08;SE模块&#xff09; class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...

全球首个30米分辨率湿地数据集(2000—2022)

数据简介 今天我们分享的数据是全球30米分辨率湿地数据集&#xff0c;包含8种湿地亚类&#xff0c;该数据以0.5X0.5的瓦片存储&#xff0c;我们整理了所有属于中国的瓦片名称与其对应省份&#xff0c;方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

linux arm系统烧录

1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 &#xff08;忘了有没有这步了 估计有&#xff09; 刷机程序 和 镜像 就不提供了。要刷的时…...

oracle与MySQL数据库之间数据同步的技术要点

Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异&#xff0c;它们的数据同步要求既要保持数据的准确性和一致性&#xff0c;又要处理好性能问题。以下是一些主要的技术要点&#xff1a; 数据结构差异 数据类型差异&#xff…...

2021-03-15 iview一些问题

1.iview 在使用tree组件时&#xff0c;发现没有set类的方法&#xff0c;只有get&#xff0c;那么要改变tree值&#xff0c;只能遍历treeData&#xff0c;递归修改treeData的checked&#xff0c;发现无法更改&#xff0c;原因在于check模式下&#xff0c;子元素的勾选状态跟父节…...

Nuxt.js 中的路由配置详解

Nuxt.js 通过其内置的路由系统简化了应用的路由配置&#xff0c;使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序

一、开发环境准备 ​​工具安装​​&#xff1a; 下载安装DevEco Studio 4.0&#xff08;支持HarmonyOS 5&#xff09;配置HarmonyOS SDK 5.0确保Node.js版本≥14 ​​项目初始化​​&#xff1a; ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...