在当今高并发、大数据的年代,体系功能优化是非常重要的。而缓存优化作为进步体系功能的一种有效手法,被广泛运用于各种场景中。其间,冷热端别离和重排序是常见的两种缓存优化方法。本篇博客将具体介绍这两种优化方法的原理、完成和运用场景,期望能为您的体系功能优化提供帮助。
缓存优化是进步体系功能的一种有效手法,其间冷热端别离和重排序是常见的两种优化方法。
缓存优化
- 冷热端别离
缓存的命中率受多种要素影响,其间最重要的要素之一是缓存的巨细。在实践运用中,经常会遇到数据集非常大的情况,假如将悉数数据都放入缓存,那么缓存的命中率就会很低,然后影响体系的功能。此刻能够考虑选用冷热端别离的战略。
所谓冷热端别离,便是将数据集分为两个部分:冷数据和热数据。冷数据指的是拜访频率低的数据,能够不用放入缓存中,而热数据指的是拜访频率高的数据,应该优先放入缓存中。经过冷热端别离,能够有效地进步缓存的命中率,然后进步体系的功能。
- 重排序
在实践运用中,数据拜访的次序往往并不是随机的,而是有必定的规律。假如按照这种规律来拜访数据,能够有效地进步缓存的命中率。因而,能够选用重排序的战略来优化缓存。
所谓重排序,便是将数据按照必定的规矩从头排序,使得拜访频率高的数据排在前面,拜访频率低的数据排在后面。这样,在拜访数据时就能够先拜访排在前面的数据,然后进步缓存的命中率。
需求注意的是,重排序的战略需求依据具体的数据集来确认,不同的数据集可能需求不同的重排序战略。一起,重排序可能会添加必定的核算量,需求在功能和命中率之间做出平衡。
举个比如
Android 中运用冷热端别离和重排序战略进步图片加载缓存命中率的比如
class ImageLoader(private val context: Context) {
private val memoryCache: LruCache<String, Bitmap>
private val diskCache: DiskLruCache
init {
// 核算可用的最大内存
val maxMemory = (Runtime.getRuntime().maxMemory() / 1024).toInt()
// 取可用内存的 1/8 作为缓存巨细
val cacheSize = maxMemory / 8
memoryCache = object : LruCache<String, Bitmap>(cacheSize) {
override fun sizeOf(key: String, value: Bitmap): Int {
// 核算 Bitmap 的巨细,单位是 KB
return value.byteCount / 1024
}
}
// 获取磁盘缓存途径
val cacheDir = context.externalCacheDir?.path ?: context.cacheDir.path
val diskCacheDir = File(cacheDir + File.separator + "image_cache")
if (!diskCacheDir.exists()) {
diskCacheDir.mkdirs()
}
diskCache = DiskLruCache.open(diskCacheDir, 1, 1, 10 * 1024 * 1024)
}
//
fun displayImage(url: String, imageView: ImageView) {
val bitmap = memoryCache.get(url)
if (bitmap != null) {
imageView.setImageBitmap(bitmap)
return
}
loadFromDiskCache(url, imageView)
loadFromNetwork(url, imageView)
}
private fun loadFromDiskCache(url: String, imageView: ImageView) {
var bitmap: Bitmap? = null
try {
val snapshot = diskCache.get(url)
if (snapshot != null) {
val inputStream = snapshot.getInputStream(0)
val fileDescriptor = (inputStream as FileInputStream).fd
bitmap = BitmapFactory.decodeFileDescriptor(fileDescriptor)
if (bitmap != null) {
memoryCache.put(url, bitmap)
imageView.setImageBitmap(bitmap)
}
}
} catch (e: IOException) {
e.printStackTrace()
}
}
private fun loadFromNetwork(url: String, imageView: ImageView) {
// 发送网络恳求获取图片数据
// ...
// 解码图片数据并显现
val bitmap = decodeBitmapFromData(imageData, reqWidth, reqHeight)
if (bitmap != null) {
memoryCache.put(url, bitmap)
try {
val editor = diskCache.edit(url)
if (editor != null) {
val outputStream = editor.newOutputStream(0)
bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream)
editor.commit()
}
} catch (e: IOException) {
e.printStackTrace()
}
imageView.setImageBitmap(bitmap)
}
}
private fun decodeBitmapFromData(data: ByteArray, reqWidth: Int, reqHeight: Int): Bitmap? {
// 解码图片数据并返回 Bitmap 目标
// ...
}
}
ImageLoader 类封装了图片加载的逻辑。它经过 LruCache 和 DiskLruCache 完成了冷热端别离的战略,将拜访频率高的图片放入 LruCache 中,而将不常用的图片放入 DiskLruCache 中。在加载图片时,先从 LruCache 中查找图片是否现已缓存,假如现已缓存则直接显现,否则从 DiskLruCache 中查找,假如也没有找到图片,则经过网络恳求获取图片并缓存到 LruCache 和 DiskLruCache 中,最终显现在 ImageView 中。
在这个比如中,重排序的完成主要体现在加载图片的次序上,先从 LruCache 中查找缓存,然后再从 DiskLruCache 中查找缓存,最终才进行网络恳求获取图片数据。这样的次序能够最大限度地进步缓存命中率,削减网络恳求的次数,一起也能够缩短图片加载的时间。
冷热端别离的完成则体现在将不常用的图片放入 DiskLruCache 中。由于 DiskLruCache 的读写速度相对较慢,所以将不常用的图片放入其间能够防止 LruCache 的缓存被占满,导致缓存筛选频频的问题。这样能够保证常用的图片能够始终缓存在 LruCache 中,进步缓存命中率。
其他运用场景和已用场景
- RecyclerView 中的 ViewHolder 缓存:在 RecyclerView 中,ViewHolder 是用来复用 item 视图的。经过将频频拜访的 View 缓存起来,能够大大进步 RecyclerView 的滑动功能,特别是在数据集较大的情况下。(多布局或许谈论列表类型的)
- 数据库查询:在数据库查询时,能够依据数据的运用频率将热数据和冷数据别离,并对热数据进行缓存,然后进步查询功能。
- JIT(Just-In-Time)编译器:在 Android 中,JIT 编译器将字节码编译成本地代码,以进步运用的履行速度。重排序能够优化 JIT 编译器的代码生成进程,进步编译速度和履行速度。
- UI 界面烘托:在 UI 界面烘托时,能够运用冷热别离的方法将常用的布局和组件缓存起来,防止每次从头烘托,然后进步界面的响应速度和功能。
- 动态加载类:在运用中运用反射动态加载类时,能够经过重排序优化类加载的进程,进步运用的响应速度。
- 预加载资源:在运用启动时,能够运用冷热别离的方法预加载一些常用的资源,防止比及需求运用时再加载,然后进步运用的启动速度和功能。
- 网络恳求:在网络恳求时,能够运用冷热别离的方法将常用的数据缓存起来,防止重复恳求,然后进步运用的响应速度和功能。
其实玩儿的仍是那个思维
总结
玩儿东西仍是要弄明白这个东西的建立根底是什么,或许负面要素有哪些。比如:
- 需求有满足的数据支持冷热别离和重排序,否则这些优化可能不会带来显着的功能进步,甚至可能会造成额外的开销。
- 冷热别离和重排序的完成需求考虑数据的生命周期,防止数据被过错地缓存或毁掉。
- 冷热别离和重排序可能会导致数据的展现次序不符合用户的期望,需求进行恰当的处理,以保证数据的展现作用。
- 在完成时需求考虑多线程安全问题,防止因并发拜访导致的数据错乱或其他异常情况。
- 在运用冷热别离和重排序时需求进行充分的测试和功能分析,以保证这些优化技能能够达到预期的功能进步作用,并且不会引进新的问题和危险。