精华内容
下载资源
问答
  • 循环优化主要包括哪些
    万次阅读 多人点赞
    2021-06-06 19:45:01

    前言

    本文隶属于专栏《100个问题搞定Java虚拟机》,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢!

    本专栏目录结构和参考文献请见100个问题搞定Java虚拟机

    正文

    循环无关代码外提

    所谓的循环无关代码(Loop-invariant Code),指的是循环中值不变的表达式

    如果能够在不改变程序语义的情况下,将这些循环无关代码提出循环之外,那么程序便可以避免重复执行这些表达式,从而达到性能提升的效果。

    循环展开

    另外一项非常重要的循环优化是循环展开(Loop Unrolling)。它指的是在循环体中重复多次循环迭代,并减少循环次数的编译优化

    循环展开的缺点显而易见:它可能会增加代码的冗余度,导致所生成机器码的长度大幅上涨。

    不过,随着循环体的增大,优化机会也会不断增加。一旦循环展开能够触发进一步的优化,总体的代码复杂度也将降低。

    循环剥离

    循环剥离指的是将循环的前几个迭代或者后几个迭代剥离出循环的优化方式。

    一般来说,循环的前几个迭代或者后几个迭代都包含特殊处理。通过将这几个特殊的迭代剥离出去,可以使原本的循环体的规律性更加明显,从而触发进一步的优化。

    计数循环

    在 C2 中,只有计数循环(Counted Loop)才能被展开。所谓的计数循环需要满足如下四个条件。

    1. 维护一个循环计数器,并且基于计数器的循环出口只有一个(但可以有基于其他判断条件的出口)。
    2. 循环计数器的类型为 int、short 或者 char(即不能是 byte、long,更不能是 float 或者 double)。
    3. 每个迭代循环计数器的增量为常数。
    4. 循环计数器的上限(增量为正数)或下限(增量为负数)是循环无关的数值

    循环判断外提

    指的是将循环中的 if 语句外提至循环之前,并且在该 if 语句的两个分支中分别放置一份循环代码。

    循环判断外提与循环无关检测外提

    所针对的代码模式比较类似,都是循环中的 if 语句。

    不同的是,后者在检查失败时会抛出异常,中止当前的正常执行路径;

    而前者所针对的是更加常见的情况,即通过 if 语句的不同分支执行不同的代码逻辑。

    更多相关内容
  • 介绍了Javascript中的循环优化需要的朋友可以参考一下
  • 前言 对于提高 JavaScript 程序的性能这个问题,最简单同时也是很容易被忽视的方法就是学习如何正确编写高性能循环语句。...两个主要因素助于改善循环性能 —— 每次迭代完成的工作和迭代次数。 在下面的内容中,
  • IE没有我们想象中笨,它知道总的循环次数还是一千万次。因此,得把这一百个十万次循环分开执行。虽然Javascript是单线程的,但也可以通过setTimeout或setInterval模拟多线程。
  • 编译优化之 - 通用循环优化

    千次阅读 多人点赞 2020-09-11 21:58:13
    循环的优化分为源码上的修改和编译器的优化,编译器能自动执行许多循环优化技术,但对源代码的修改可辅助编译器就行优化处理。 1. 源码上的优化 1. 多重循环的“外小内大”   在多重循环中,采用迭代次数较小的...

    前言

      循环是程序中最常见结构,针对循环已有众多的优化技术。循环的优化分为源码上的修改和编译器的优化,编译器能自动执行许多循环优化技术,但对源代码的修改可辅助编译器就行优化处理。

    1. 源码上的优化

    1. 多重循环的“外小内大”

      在多重循环中,采用迭代次数较小的循环驱动内层迭代次数较大的循环能减少内存的消耗,如下示例:

    for (int i = 0; i < 10000; i++) {
        for (int j = 0; j < 200; j++) {
    
        }
    }
    改为:
    for (int i = 0; i <200 ; i++) {
        for (int j = 0; j < 10000; j++) {
    
        }
    }
    
    2. 循环变量实例化放在循环外

    如下示例:

    int i,j;
    for (i = 0; i <200 ; i++) {
        for (j = 0; j < 10000; j++) {
    
        }
    }
    
    3. 循环无关的表达式放到循环外

    如下示例:

    int i,j;
    for (i = 0; i <200 ; i++) {
        for (j = 0; j < 10000; j++) {
              j = i*j*x/(y-1);
        }
    }
    改为:
    int i,j,tmp;
    tmp = x/(y-1);
    for (i = 0; i <200 ; i++) {
        for (j = 0; j < 10000; j++) {
              j = i*j*tmp;
        }
    }
    
    4. 消除循环终止时的方法调用

    如下示例:

    for (int i = 0; i < vec.size(); i++) {
    
    }
    改为:
    int size = vec.size();
    for (int i = 0; i < size; i++) {
    
    }
    
    5. 循环外部捕获异常

      在循环外部捕获异常能有效减少内层消耗。一般而言,foreach 循环优先于传统的 for 循环。

    6. 循环的 i++ 改为 ++i

      效率上来说++i 比 i++来的更有效率(后置操作符必须先保存操作数原来的值),但现代编译器上这个影响会很小。


    2. 编译器角度的优化

    1. 循环展开(loop Unrolling)

      重组循环,以便每次迭代多次使用加载的值,让一拍流水线上尽可能满。在流水线中,会因为指令顺序安排不合理而导致CPU等待空转,影响流水线效率。循环展开为编译器进行指令调度带来了更大的空间。
    如下示例:

    do j = 1,2*n
        do i = 1,m
            A(j) = A(j) + B(i)
        enddo
    enddo
    
    Unrolling之后:
    do j = 1,2*n by 2
        do i = 1,m
            A(j) = A(j) + B(i)
            A(j+1) = A(j+1) + B(i)
        enddo
    enddo
    
    2. 循环分块(loop tiling)

      由于内存空间有限,代码访问的数据量过大时,无法一次性将所需要的数据加载到设备内存,循环分块能有效提高处理器 cache 上的访存效率,改善数据局部性。(分块应用于外部循环,它会增加计算的空间和时间局部性;分块应与缓存块一起使用,因为这样可以提高最内部软件流水线的效率)。示意如图:
    loop1

    如下示例:

    do j = 1,2*n
        do i = 1,m
            A(j)= A(j) + B(i)
        enddo
    enddo
    
    Tiling之后:
    do jj = 1,2*n by 2
        do i = 1,m
            do j = jj, jj+2-1
                A(j)= A(j)+B(i)
            enddo
        enddo
    enddo
    
    Unroll and Jam之后:
    do jj = 1,2*n by 2
        do i = 1,m
            A(j)= A(j)+B(i)
            A(j+1)= A(j+1)+B(i)
        enddo
    enddo
    

    更多关于 loop tiling 的优化方法可参见论文:《Augmenting Loop Tiling with data Alignment for Improved Cache Performance》《Automatic Tiling of Iterative Stencil Loops》《面向局部性和并行优化的循环分块技术》

    3. 循环交换(loop interchange)

      内外层循环交换,改善空间局部性,并最大限度地利用引入缓存的数据。对循环进行重新排序,以最大程度地减少跨步并将访问模式与内存中的数据存储模式对齐。
    如下示例:

    do i=1,n
        do j=1,n
            A(i,j)=B(i,j)*C(i,j)
        enddo
    enddo
    
    interchange之后:
    do j=1,n
        do i=1,n
            A(i,j)=B(i,j)*C(i,j)
        enddo
    enddo
    
    4. 循环融合(loop fusion)

      将相邻或紧密间隔的循环融合在一起,减少的循环开销和增加的计算密度可改善软件流水线,数据结构的缓存局部性增加,编译器在某些情况下未执行融合,需要手动完成。
    如下示例:

    for(i = 0; i < size; ++i){
        A(i) = a(i) + b(i);
        c(i) = 2*a(i);
    }
    for(i = 1; i < size-1; ++i){
        D(i) = c(i) + a(i);
    }
    
    fusion之后:
    A(0) = a(0) + b(0);
    c(0) = 2*a(0);
    A(size-1) = a(size-1) + b(size-1);
    c(size-1) = 2*a(size-1);
    for(i = 1; i < size-1; ++i){
        A(i) = a(i) + b(i);
        c(i) = 2*a(i);
        D(i) = c(i) + a(i);
    }
    
    5. 循环分裂(loop fission)

      将循环分成多个循环,可以在有条件的循环中使用,分为无条件循环和含条件循环。
    如下示例:

    for(i = 0; i < size; ++i){
        A(i) = a(i) + b(i);
        c(i) = 2*a(i);
        if(temp[i] > data)
            d(i) = a(i);
    }
    
    fission之后:
    for(i = 0; i < size; ++i){
        A(i) = a(i) + b(i);
        c(i) = 2*a(i);
    }
    for(i = 0; i < size; ++i){
        if(temp[i] > data)
            d(i) = a(i);
    }
    
    6. 循环剥离(loop peeling)

      剥离 k 次迭代意味着从循环主体中删除这些迭代并将其放置在循环主体之前或之后。
    如下示例:

    do i=1,n
        Y(i,n) = (1.0 - x(i,1))*y(1,n) + x(i,1)*y(n,n)
    enddo
    
    peeling之后:
    t2 = y(n,n)
    t1 = y(1,n)
    y(1,n) = (1.0 - x(1,1))*t1 + x(1,1)*t2
    do i=2,n-1
        Y(i,n) = (1.0 - x(i,1))*t1 + x(i,1)*t2
    enddo
    y(n,n) = (1.0 - x(n,1))*t1 + x(n,1)*t2
    
    7. 循环强度减弱(Strength reduction in loops)

      使用简单的表达式来替换复杂的表达式。
    例如,除法替换,如下示例:

    z(i) = x(i)/y(i)
    w(i) = u(i)/v(i)
    
    Strength reduction之后:
    tmp = 1.0/(y(i)*v(i))
    z(i) = x(i)*v(i)*tmp
    w(i) = u(i)*y(i)*tmp
    

    References:

    • https://blog.csdn.net/qq_37436998/article/details/100055770
    • https://www.cs.colostate.edu/~mstrout/CS553Fall07/Slides/lecture27-tiling.pdf
    • http://users.cecs.anu.edu.au/~Alistair.Rendell/sc02/module2b.pdf
    展开全文
  • 这也是为什么近期我一直不怎么推崇用jQuery,这框架的API设定就误导人们走上歧途之嫌。 代码如下: $.fn.beautifyTable = function(options) { //定义默认配置项,再用options覆盖 return this.each(function() { ...
  • 主要介绍了C语言中对于循环结构优化的一些入门级方法,包括算法设计的改进来提高一些并行性等方法,要的朋友可以参考下
  • 在系统性能优化的时候循环和字符串处理一直是非常值得注意的地方。从心态上我们一定不能把自己的眼界放在十次或者是百次循环的层次上,也不能把自己要处理的字符串当做是十个二十个字符。每次遇到循环都要假定这个...
  • java for循环及其优化

    千次阅读 2021-03-16 11:37:30
    for循环1.首先知道,for循环的3个表达式的意思:表达式1: 一般为赋值表达式,给控制变量赋初值;表达式2: 关系表达式或逻辑表达式,循环控制条件;表达式3: 一般为赋值表达式,给控制变量增量或减量。3个表达式都...

    for循环

    1.首先知道,for循环的3个表达式的意思:

    表达式1: 一般为赋值表达式,给控制变量赋初值;

    表达式2: 关系表达式或逻辑表达式,循环控制条件;

    表达式3: 一般为赋值表达式,给控制变量增量或减量。

    3个表达式都可以为空,第2个表达式为空,表示条件一直为true,for无限循环。

    for(;;){

    System.out.println("hello");

    }

    //输出结果:无限输出,疯狂输出

    hello

    hello

    ……

    2.第1个初始化表达式,可以对多个同类型变量赋值;第3个条件若有多个条件,可以用逻辑运算符(&& 、 || 、!)连接;第3个表达式可以用逗号隔开多个表达式

    for(int i=0,j=0;i<10&&j<5;i++,j++){

    System.out.println("i="+i+",j="+j);

    }

    for循环优化

    1、在参数表达式上优化

    1.1、不要在表达式上做复杂运算

    如下代码

    List list = new ArrayList<>();

    for (int i = 0; i < list.size(); i++) {

    }

    for的第2个表达式上面用了list.size(),这样就导致了每次循环到这里都要去进行一次list的个数计算,会降低性能;应该改为这样

    List list = new ArrayList<>();

    for (int i = 0, len = list.size(); i < len; i++) {

    }

    1.2、循环嵌套,应该采用外大内小型;也就是循环次数多的for放在外层,循环次数少的for放在内层。

    for(int i=0;i<1000;i++){

    for(int j=0;j<100;j++){

    for(int k=0;k<10;k++){

    function(i,j,k);

    }

    }

    }//耗时333 3105 纳秒

    改为

    for(int k=0;k<10;k++){

    for(int j=0;j<100;j++){

    for(int i=0;i<1000;i++){

    function(i,j,k);

    }

    }

    }//耗时282 7670 纳秒

    2、无用逻辑要放在循环外,避免重复计算发生

    int a = 10, b = 11;

    for (int i = 0; i < 10; i++) {

    i = i * a * b;

    }

    改为

    int c = a * b;

    for (int i = 0; i < 10; i++) {

    i = i * c;

    }

    3、try catch语句放到循环外,因为抓捕异常是非常耗时的,所以放到for外面一次抓取

    for (int i = 0; i < 10; i++) {

    try {

    } catch (Exception e) {

    }

    }

    改为

    try {

    for (int i = 0; i < 10; i++) {

    }

    } catch (Exception e) {

    } 参考资料: http://www.cnblogs.com/ywl925/p/3608192.html http://blog.csdn.net/liushuijinger/article/details/41546347 http://cgs1999.iteye.com/blog/1596671

    展开全文
  • 性能优化-多层嵌套for循环如何优化

    千次阅读 2021-03-08 07:06:06
    /*** @program: cwl-performance-optimization* @description: 测试for循环-嵌套循环* @author: ChenWenLong* @create: 2019-11-22 11:27**/public class TestNestedLoop {// 当需要嵌套循环时 外层循环越小 性能越...

    代码示例

    package com.cwl.po;

    /**

    * @program: cwl-performance-optimization

    * @description: 测试for循环-嵌套循环

    * @author: ChenWenLong

    * @create: 2019-11-22 11:27

    **/

    public class TestNestedLoop {

    // 当需要嵌套循环时 外层循环越小 性能越好

    // 例如 10*100*1000 与 1000*100*10 相互比较

    public static void main(String[] args) {

    // 测试最终结果发现当嵌套循环越大 两者相差性能比越大

    System.out.println(testOutSide());

    System.out.println(testInSide());

    }

    /**

    * 功能描述:

    * 〈测试内层循环逐步增大〉

    *

    * @params : []

    * @return : long

    * @author : cwl

    * @date : 2019/11/22 11:36

    */

    private static long testInSide() {

    long begin = System.currentTimeMillis();

    int d = 0;

    for(int a=0;a<1000;a++){

    for(int b=0;b<10000;b++){

    for (int c=0;c<100000;c++){

    d = a+b+c;

    }

    }

    }

    long end = System.currentTimeMillis();

    System.out.println(d);

    return end - begin;

    }

    /**

    * 功能描述:

    * 〈测试内层循环逐步减小〉

    *

    * @params : []

    * @return : long

    * @author : cwl

    * @date : 2019/11/22 11:37

    */

    private static long testOutSide() {

    long begin = System.currentTimeMillis();

    int d = 0;

    for(int a=0;a<100000;a++){

    for(int b=0;b<10000;b++){

    for (int c=0;c<1000;c++){

    d = a+b+c;

    }

    }

    }

    long end = System.currentTimeMillis();

    System.out.println(d);

    return end - begin;

    }

    }

    本文同步分享在 博客“cwl_java”(CSDN)。

    如有侵权,请联系 support@oschina.cn 删除。

    本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

    展开全文
  • 性能优化——for循环

    千次阅读 2022-01-28 14:39:09
    for循环优化;线程池;
  • 循环优化与多面体模型

    千次阅读 2019-09-22 21:22:08
    循环通常是数据并行应用的最密集计算段,因此循环优化直接影响性能。当面对嵌套循环时,分配给线程的计算粒度将直接影响性能。循环转换如Fission(循环裂变)与Fusion(循环融合)的嵌套式循环可促使并行化,并提高...
  • 嵌套For循环性能优化案例

    千次阅读 2021-02-12 23:59:02
    1案例描述某日,在JavaEye上看到一道面试题,题目是这样的:请对以下的代码进行优化for (int i = 0; i < 1000; i++)for (int j = 0; j < 100; j++)for (int k = 0; k < 10; k++)testFunction (i, j, k);2 ...
  • Python笔记:loop循环优化删改)

    千次阅读 2019-08-30 21:52:13
    我们知道,循环是一次一次的执行我们的要求,优化的关键点就是最小化循环的工作量*(当然只有循环次数大的时候才意义,太小的优化效果几乎忽略不计)*。 如下为一个典型的loop循环: import random lowerlist =...
  • for 循环优化

    千次阅读 2022-02-14 14:27:18
    经常使用循环耗时计算的操作,尤其是 for 循环,如果处理不好,耗时就比较长,如果处理书写得当将大大提高效率,下面总结几条 for 循环的常见优化方式。 一、消除循环终止判断时的方法调用 优化前: for (int i = 0;...
  • 循环也正是程序优化中非常让人头疼的一环,我们往往需要不断去优化程序的复杂度,却因循环而纠结在时间复杂度和空间复杂度之间的抉择。 在 javascript 中,3种原生循环,for () {}, while () {}和do {} while ...
  • JavaScript性能优化——循环优化

    千次阅读 2019-05-18 16:22:24
    循环是我们在写代码时经常用到的一种结构,而往往在考虑性能优化时,循环优化能带来很大的收益,特别是当我们不得不循环多次时,如果没对性能进行优化,那毫无疑问会带来性能的负担。 循环的类型 1.for循环 for...
  • 参考资料 《编译技术》 邵老师PPT 跳过目录 目录 循环优化 循环不变式的代码外提 循环展开 归纳变量的优化和条件判断的替换 其它循环优化方法 in_line(内联)展开 循环优化 二八定律 (Pareto Principle) “程序...
  • 前端项目性能优化方案有哪些

    千次阅读 多人点赞 2022-03-07 10:32:27
    前端项目性能优化方案汇总
  • java 优化双重for循环

    千次阅读 2022-04-07 13:40:43
    首先我们要两个对象分别是 学生信息 和 学生住宿信息 class Student { //学生id private Integer studentUserId; //学生名称 private String name; } class Student { //学生id private Integer ...
  • 多重循环性能优化

    千次阅读 2018-12-19 09:16:41
    优化后的多重for循环可以提升大半的效率。 方法 一、实例化变量尽量放在for循环体外,只实例化一次。 二、普通变量改为寄存器变量,如i++改为++i。前置递增运算避免了不必要的工作,它把值加1后直接返回改变了运算...
  • Java优化for循环嵌套的高效率方法

    千次阅读 2021-02-12 23:59:03
    前几天人问过我一个问题,就是两个嵌套for循环执行效率的问题,问什么好的办法替换。当时我想了想,实在想不起来,哎,惭愧!!! 请教了答案,恍然大悟。比如:两个list中分别装有相同的对象数据。 list1中3...
  • 【编译原理】中间代码优化(三) 循环优化

    千次阅读 多人点赞 2020-06-29 18:02:54
    为了进行循环优化,首先需要确定的是程序流图中哪些基本块构成一个循环。按照结构程序设计思想,程序员在编程时应使用高级语言所提供的结构性的循环语句来编写循环。而由高级语言的循环语句所形成的循环,是不难找出...
  • 如何优化Python中的嵌套for循环

    千次阅读 2021-04-27 03:41:58
    纽比广播如果不受内存限制,优化numpy中嵌套循环的第一步是使用广播并以矢量化的方式执行操作:import numpy as npdef mb_r(forecasted_array, observed_array):"""Returns the Mielke-Berry R value."""assert len...
  • C++ For循环优化

    2010-07-22 19:01:58
    C++循环冒泡法优化 在看到for循环冒泡排序(c++) 后 再次优化了一下,它的程序不能运行,我运行优化的成功了,对初学者理解很大帮助(还有注释)
  • 数据少的时候还好,一旦数据多就是成倍的循环次数,性能不好,尝试优化一下。假如两次循环都是1000个元素,那么循环次数是:1000*1000之前的双层for循环写法: 优化后写法 相当于一个for循环就能搞定 优化之后的...
  • c语言循环优化

    千次阅读 2014-01-13 11:53:27
    循环优化 提高程序效率的核心是对影响代码执行速度的关键程序段进行优化。在任何程序中,最影响代码速度的 往往是循环语句,特别是多层嵌套的循环语句。因此,掌握循环优化的各种实用技术是提高程序效率的 ...
  • 关于for循环嵌套for循环优化问题

    千次阅读 2020-06-25 13:54:53
    对于for循环的嵌套问题 我们常见就是这样: for (int i = 0; i < 1000; i++){ for (int j = 0; j < 100; j++){ for (int k = 0; k < 10; k++){ system.out.println(i+"====="+j+"====="+k); } } } ...
  • 多重for循环优化,提升运行效率

    万次阅读 多人点赞 2018-07-18 09:37:08
    循环次数较少的时候一般...客户体验会非常不好,才研究这个情况的,事实证明,优化后的多重for循环提升了一大半的效率,是不是很神奇。 当然,本文也借鉴其他同胞的方法。 实例化变量放在for循环外,减少实...
  • 优化循环的方法-循环展开

    千次阅读 2019-01-16 11:11:36
    更多文章 循环展开是一种程序变换,通过增加每次迭代计算的元素的数量,减少循环的迭代次数。 用代码来说明就是将 for (i = 0; i &lt; len; i++) { ...循环展开对于算术运算来说,优化的作用是很大...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 576,924
精华内容 230,769
热门标签
关键字:

循环优化主要包括哪些