这篇文章我们来聊聊什么是程序的局部性原理

01、前言

作为有追求的程序员,我们日常在写代码的时候往往都会运用很多奇技淫巧,不单单是为了炫耀我们的技术,更是为了追求更高的效率。了解局部性原理,可以有效的帮助我们理解和写出更好的代码,对于局部性原理可能有的小伙伴知道,有的小伙伴不知道,知道的小伙伴就当做复习知识点,不知道的小伙伴也没关系,接着往下看就知道了。

02、什么是局部性原理

说到局部性原理,那我们首先要知道什么是局部性原理,局部性原理分为两部分:

  • 时间局部性:指的是在程序运行过程中最近被引用到的存储器位置在程序执行后期还会被多次引用到的可能性很大。
  • 空间局部性:指的是程序运行过程中如果一个存储器的位置被引用,那么在程序执行后期该存储器附近的位置被引用的可能性很大。

简单来说就是一个变量在程序运行过程中,如果被引用过一次,那后续很有可能会再被引用到;一个变量被访问到过后,这个变量所在的位置附近的位置很有可能在程序后续运行中被访问到。

03、示例

上面是通过理论来说明的,下面我们通过一段代码来看看局部性y原理

1
2
3
4
5
6
7
public int sum(int[] array) {
        int sum = 0;
        for (int i = 0; i < array.length; i++) {
            sum = sum + array[i];
        }
        return sum;
    }

从上面的这段代码来看,就是一个很简单的数组元素求和,这里我们主要看 sum 和 array 两个变量,我们可以看到 sum 在每次循环中都会用到,另外它只是一个简单变量,所以我们可以看到,sum 是符合我们上面提到的时间局部性,再访问一次后还会被继续访问到,但是它不存在我们所说的空间局部性了。

相反的,array 数组中的每个元素只访问一次,另外数组底层的存储是连续的,所以 array 变量符合我们上面提到的空间局部性,但是不符合时间局部性。

这只是局部性原理的简单示例,对于局部性原理还有很多地方会用到,我们如果能熟练的掌握和使用,对我们的帮助会很大的。

04、相关应用

4.1、CPU 缓存

上面的示例其实很简单,相信大家都能理解,另外局部性原理其实在我们日常使用的软件中随处可见,并且在操作系统中也少不了。我们知道 CPU 的速度是非常快的,而且 CPU 与内存之间有多级缓存,如下图(图片来源于网络)

为了充分的利用 CPU,操作系统会利用局部性原理,将高频的数据从内存中加载的缓存中,从而加快 CPU 的处理速度。

4.2、广义局部性

其实我们的局部性原理不单单是上面提到的狭义性的局部性,还可以是广义的局部性。我们系统里面的热点数据,CDN 数据,微博的热点流量等等这些都利用了局部性原理。只是我们可能没有意识到而已,实际上已经在使用了。我们会通过 Redis 缓存热点数据,会通过 CDN 提前加载图片或者视频资源,等等,都是因为这些数据本身就符合局部性原理,合理的利用局部性可以得到了能效、成本上的提升。

4.3、利弊结合

任何事情都是多面性的,局部性原理虽然我们使用起来很不错,可以提高系统性能,但是在有些场景下,我们是需要避免局部性原理的出现的。或者说出现了这种情况,我们需要人工处理。我们可以试想一下,如果在我们的一个大数据处理平台上,由于局部性原理的存在,导致我们部分节点数据庞大运算吃力,部分节点数据量小十分空闲,这种情况自然是不合理,我们就需要把数据按照业务场景进行重新分配,以达到整个集群的最大利用。

05、总结

今天给大家介绍了一下局部性原理,我们提到了时间局部性和空间局部性,通过一个代码示例和几个业务场景给大家简单介绍了局部性的使用。最后也提到局部性原理有利也有弊,我们需要根据业务场景和需求合理话的使用。

最后欢迎大家到我们《Java 极客技术》知识星球中来跟我们一起学习,一起进步。

Java Geek Tech wechat
欢迎订阅 Java 极客技术,这里分享关于 Java 的一切。