程序性能优化-局部性原理

更多文章

概念

一个编写良好的计算机程序常常具有良好的局部性,它们倾向于引用邻近于其他最近引用过的数据项的数据项,或者最近引用过的数据项本身,这种倾向性,被称为局部性原理。有良好局部性的程序比局部性差的程序运行得更快。

局部性通常有两种不同的形式:

  • 时间局部性

在一个具有良好时间局部性的程序中,被引用过一次的内存位置很可能在不远的将来被多次引用。

  • 空间局部性

在一个具有良好空间局部性的程序中,如果一个内存位置被引用了一次,那么程序很可能在不远的将来引用附近的一个内存位置。

时间局部性示例

function sum(arry) {
    let i, sum = 0
    let len = arry.length

    for (i = 0; i < len; i++) {
        sum += arry[i]
    }

    return sum
}

在这个例子中,变量sum在每次循环迭代中被引用一次,因此,对于sum来说,具有良好的时间局部性

空间局部性示例

具有良好空间局部性的程序

// 二维数组
function sum1(arry, rows, cols) {
    let i, j, sum = 0

    for (i = 0; i < rows; i++) {
        for (j = 0; j < cols; j++) {
            sum += arry[i][j]
        }
    }
    return sum
}

空间局部性差的程序

// 二维数组
function sum2(arry, rows, cols) {
    let i, j, sum = 0

    for (j = 0; j < cols; j++) {
        for (i = 0; i < rows; i++) {
            sum += arry[i][j]
        }
    }
    return sum
}

再回头看一下时间局部性的示例,像示例中按顺序访问一个数组每个元素的函数,具有步长为1的引用模式。

如果在数组中,每隔k个元素进行访问,就称为步长为k的引用模式。

一般而言,随着步长的增加,空间局部性下降。

这两个例子有什么区别?区别在于第一个示例是按照列顺序来扫描数组,第二个示例是按照行顺序来扫描数组。

数组在内存中是按照行顺序来存放的,结果就是按行顺序来扫描数组的示例得到了步长为rows的引用模式;
而对于按列顺序来扫描数组的示例来说,其结果是得到一个很好的步长为1的引用模式,具有良好的空间局部性。

性能测试

运行环境

  • cpu: i5-7400
  • 浏览器: chrome 70.0.3538.110

对一个长度为9000的二维数组(子数组长度也为9000)进行10次空间局部性测试,时间(毫秒)取平均值,结果如下:

所用示例为上述两个空间局部性示例

按列排序 按行排序
124 2316

从以上测试结果来看,二维数组按列顺序访问比按行顺序访问快了1个数量级的速度。

测试代码

const arry = []
let [num, n, cols, rows] = [9000, 9000, 9000, 9000]
let temp = []

while (num) {
    while (n) {
        temp.push(n)
        n--
    }
    arry.push(temp)
    n = 9000
    temp = []
    num--
}

let last, now, val

last = new Date()
val = sum1(arry, rows, cols)
now = new Date()
console.log(now - last)
console.log(val)

last = new Date()
val = sum2(arry, rows, cols)
now = new Date()
console.log(now - last)
console.log(val)

function sum1(arry, rows, cols) {
    let i, j, sum = 0

    for (i = 0; i < rows; i++) {
        for (j = 0; j < cols; j++) {
            sum += arry[i][j]
        }
    }
    return sum
}

function sum2(arry, rows, cols) {
    let i, j, sum = 0

    for (j = 0; j < cols; j++) {
        for (i = 0; i < rows; i++) {
            sum += arry[i][j]
        }
    }
    return sum
}

参考资料

深入理解计算机系统

原文地址:https://www.cnblogs.com/woai3c/p/10281706.html

时间: 2024-10-29 03:40:38

程序性能优化-局部性原理的相关文章

Java程序性能优化——性能调优层次

为了提升系统性能,开发人员可以从系统的各个角度和层次对系统进行优化.除了最常见的代码优化外,在软件架构上.JVM虚拟机层.数据库以及操作系统层都可以通过各种手段进行调优,从而在整体上提升系统的性能. 设计调优 设计调优处于所有调优手段的上层,它往往需要在软件开发之前进行.在软件开发之初,软件架构师就应该评估系统可能存在的各种潜在的问题,并给出合理的设计方案.由于软件设计和架构对软件整体有决定性的影响,所以,设计调优对系统性能的影响也是最大的.如果说,代码优化.JVM优化都是对系统微观层面上"量&

程序性能优化之SQL篇

如果说功能是程序的躯体,那么性能就是程序的灵魂.完整的功能可以保证程序的躯体是健全的,而良好的性能才是程序灵魂的象征,本文就程序的性能优化做简单的介绍. 最近对程序的性能的体会尤为深刻.最近做了一个数据查询和显示的功能,从7张表大概1500条数据中查询25条数据并且显示出来,时间消耗1秒钟.我的计算机参数为:CPU:i5处理器,4G内存.这个执行速度相当的慢,好在我查询的数据量比较小,等待时间不是很多,但是程序性能优化确实刻不容缓. 仔细分析了程序,发现有很多地方都是需要修改的,我们先从数据库开

Java程序性能优化——设计优化

原文出自:http://blog.csdn.net/anxpp/article/details/51914119,转载请注明出处,谢谢! 1.前言 OK,之前写了一篇文章:"23种设计模式介绍以及在Java中的应用"详细介绍了如何将设计模式应用到Java编程中,而本文旨在介绍如何利用他们优化我们的程序,使其性能更佳. 设计模式的详细介绍请参照上面链接中的文章,不是本文的重点. 而Java程序的性能优化,不一定就仅仅是以提高系统性能为目的的,还可能是以用户体验.系统可维护性等为目的. 2

Java程序性能优化——性能指标

性能概述 为什么程序总是那么慢?它现在到底在干什么?时间都花到哪里去了?也许,你经常会抱怨这些问题.如果是这样,那说明你的程序出了性能问题.和功能性问题相比,性能问题在有些情况下,可能并不算什么太大的问题,将就一下,就过去了!但是,严重的性能问题会导致程序瘫痪.假死.直至崩溃.本节就先来认识性能的各种表现和指标. 看懂程序的性能 读客户端程序而言,拙劣的性能会严重影响用户体验:界面停顿.抖动(非动作特效).响应迟钝等问题会遭到用户不停的抱怨.一个典型的例子就是Eclipse IDE工具在Full

Web应用程序性能优化学习笔记

Web应用程序性能优化学习笔记 1. 使用瀑布图初步诊断网站性能瓶颈 一般来说,打开一个网页的速度会受到以下几项的影响: 1) 服务器花了太长的时间将.aspx页面的内容转化为html. 2) .aspx页面花了太长的时间从服务器端将内容发送到客户端. 3) 页面上的图片或者flash文件花了太长的时间从服务器端发送到客户端. 4) JavaScript和CSS文件阻塞页面渲染. 我们可以使用“瀑布图”来确定一个页面的性能问题是由于哪一项造成的.FireBug.Chrome自带的“开发人员工具”

C++应用程序性能优化(二)——C++对象模型

C++应用程序性能优化(二)--C++对象模型 一.C++对象模型与性能优化 对象模型是面向对象程序设计语言的重要方面,会直接影响面向对象语言编写程序的运行机制以及对内存的使用机制,因此了解对象模型是进行程序性能优化的基础.只有深入理解C++对象模型,才能避免程序开发过程中一些不易发现的内存错误,从而改善程序性能,提高程序质量. 二.C++程序的内存分布 1.程序内存分布简介 通常,计算机程序由代码和数据组成,因此代码和数据也是影响程序所需内存的主要因素.代码是程序运行的指令,比如数学运算.比较

C++应用程序性能优化(四)——C++常用数据结构性能分析

C++应用程序性能优化(四)--C++常用数据结构性能分析 本文将根据各种实用操作(遍历.插入.删除.排序.查找)并结合实例对常用数据结构进行性能分析. 一.常用数据结构简介 1.数组 数组是最常用的一种线性表,对于静态的或者预先能确定大小的数据集合,采用数组进行存储是最佳选择.数组的优点一是查找方便,利用下标即可立即定位到所需的数据节点:二是添加或删除元素时不会产生内存碎片:三是不需要考虑数据节点指针的存储.然而,数组作为一种静态数据结构,存在内存使用率低.可扩展性差的缺点.无论数组中实际有多

C++应用程序性能优化(五)——操作系统的内存管理

C++应用程序性能优化(五)--操作系统的内存管理 一.操作系统内存管理简介 长期以来,在计算机系统中,内存都是一种紧缺和宝贵的资源,应用程序必须在载入内存后才能执行.早期,在内存空间不够大时,同时运行的应用程序的数量会受到很大的限制,甚至当某个应用程序在某个运行时所需内存超过物理内存时,应用程序就会无法运行.现代操作系统(Windows.Linux)通过引入虚拟内存进行内存管理,解决了应用程序在内存不足时不能运行的问题.本质上,虚拟内存就是要让一个程序的代码和数据在没有全部载入内存时即可运行.

Java程序性能优化技巧

多线程.集合.网络编程.内存优化.缓冲..spring.设计模式.软件工程.编程思想 1.生成对象时,合理分配空间和大小new ArrayList(100); 2.优化for循环Vector vect = new Vector(1000);for( inti=0; i<vect.size(); i++){ ...}for循环部分改写成:int size = vect.size();for( int i=0; i>size; i++){ ...} 如果size=1000,就可以减少1000次si