精华内容
下载资源
问答
  • 前言 本文隶属于专栏《100个问题搞定Java虚拟机》,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢! 本专栏目录结构和参考文献...另外一项非常重要的循环优化是循环展开(Loop Unroll

    前言

    本文隶属于专栏《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 语句的不同分支执行不同的代码逻辑。

    展开全文
  • c语言循环优化

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

    C语言常规优化策略


    3 循环优化


    提高程序效率的核心是对影响代码执行速度的关键程序段进行优化。在任何程序中,最影响代码速度的

    往往是循环语句,特别是多层嵌套的循环语句。因此,掌握循环优化的各种实用技术是提高程序效率的

    利器,也是一个高水平程序必须具备的基本功。
    本节有关各种循环优化技术的讨论基本上以下面的一个程序段为对象,程序的涵义为:对于两个给定的

    数组a、b,计算a[8]b[8]+a[12]b[12]+...+a[84]b[84]的值。原始的代码为:
    // 版本0
    prod=0;
    i=1;
    while (i<=20)
    {
     x=*(a+4*i+4);
     y=*(b+4*i+4);
     z=x*y;
     prod+=z;
     i++;
    }
    常用的循环优化技术包括代码外提、删除冗余运算、强度削弱、变换循环控制条件、合并已知量以及删

    除无用赋值等。下面我们围绕这一例子来介绍这些内容。

    3.1 代码外提


    代码外提是指将循环体中与循环变量无关的运算提出,并将其放到循环之外,以避免每次循环过程中的

    重复操作。
    在原始代码中,计算x、y的值时,重复使用到a+4, b+4操作,由于它们与循环变量i无关,可以放到循环

    之外一次执行完成:
    // 版本1
    prod=0;
    i=1;
    a1=a+4;
    b1=b+4;
    while (i<=20)
    {
     x=*(a1+4*i);
     y=*(b1+4*i);
     z=x*y;
     prod+=z;
     i++;
    }

    3.2 删除冗余运算


    在版本1中,循环体内执行了两次4*i的操作,通过引入中间变量保留这一结果,可以删除冗余计算。
    // 版本2
    prod=0;
    i=1;
    a1=a+4;
    b1=b+4;
    while (i<=20)
    {
     j=4*i;
     x=*(a1+j);
     y=*(b1+j);
     z=x*y;
     prod+=z;
     i++;
    }


    3.3 强度削弱与合并已知量

    版本2还有进一步优化的必要,其中4*i这一乘法操作可根据问题的特点改换成加法操作。因为在两次相

    邻的循环执行过程中,i的值相差4,为一个常数,因此可将j=4*i改换成j+=4,j的初值在循环外设置成

    j=4*(i-1)。这一步称为强度削弱。在本例子中,由于i的初值为1,数j的初值为0,这一步称为合并已知

    量。
    // 版本3
    prod=0;
    i=1;
    j=0;
    a1=a+4;
    b1=b+4;
    while (i<=20)
    {
     j+=4;
     x=*(a1+j);
     y=*(b1+j);
     z=x*y;
     prod+=z;
     i++;
    }

    3.4 变换循环控制条件

    从版本3可以看到,循环变量i在循环体中除自身引用外,已不起任何作用,因此,可以将i从循环中删去

    ,其控制作用交给变量j来完成,由于在每次进入循环时,i、j之间总是保持关系j=4(i-1),从而可将循

    环条件所改成j<=76。
    // 版本4
    prod=0;
    j=0;
    a1=a+4;
    b1=b+4;
    while (j<=76)
    {
     j+=4;
     x=*(a1+j);
     y=*(b1+j);
     z=x*y;
     prod+=z;
    }
    在这一最后的版本中,除了变换循环控制条件外,还将有关i的无用赋值从循环内外全部驱除出去了。下

    表列出了原始版本和最终版本在循环体内一些基本操作的差异:
      加法次数 乘法次数 赋值次数
    原始版本 6  3  3
    最终版本 4  1  3
    其中,”+=“及”++”均算作一次加法。由此可见最终版本的效率约为原始版本的2倍。

    3.5 循环优化的其它措施

    循环优化是一个非常古老的话题,从第一个计算机程序诞生至今,一代一代的程序员已经积类起很多循

    环优化的知识。例如,有一种称之为循环展开的方法在50,60年代非常流行,至今虽然一般程序员已不常

    采用,但在一些特别追求效率的领域,如游戏程序编制,计算机动画等,还能找到这一方法的一丝踪迹

    。循环展开的思想非常简单,如我们要计算一个数组前20项之和,通常的程序为:
    s=0;
    for (i=0; i<20;i++)
     s+=a[i];
    采用最极端的循环展开法,上述程序可以写成:
    s=a[0]+a[1]+...+a[19]
    当然在程序中是不允许出现省略号的,这里我们只是一种示意性说明。很显然,根端的循环展开法在大

    部分情况下是不可取的,例如,要计算数组前100项的和,我们决不会愚蠢到在程序中写出100数相加的

    复杂表达式,即使你有时间和耐心去完成这项乏味的工作,大部分的编译程序都会对此提出警告,或者

    在执行优化的过程中建议对表达式进行简化。一种变通的方式为: 仅在循环中展开几步,但仍保留循环

    结构:
    s=0;
    for (i=0; i<20;)
    {
     s+=a[i++];
     s+=a[i++];
     s+=a[i++];
     s+=a[i++];
    }
    据说,将循环展开2~7步可以提高程序效率达10%~20%。即便如此,除非无路可走,我是决不会采纳这

    种措施的。
    在循环优化的诸多措施中,最有效的措施要数强度削弱了,只有强度削弱才是改善循环效率的关键,作

    为一个例子,大家可以对前面给出的中点线算法进行优化,将循环内的乘法全改为加法来完成。对于本

    节给出的例子和中点线算法,循环中的乘法都是与循环变量线性相关的,对于非线性相关的情况,也能

    够经过多次强度削弱,从而将乘法改变成加法。下面的例子是要计算前n个整数的平方和,我们来看看循

    环变量的平方是怎样由加法来完成的。
    S=0;
    for (i=1; i<=n; i++)
     S+=i*i;
    首先,两次连续的循环中i相差1,从而(i+)*(i+1)与i*i相差2*i+1,因此,上面的程序可以改进为:
    S=0;
    j=0;
    for (i=1; i<=n; i++)
    {
     j=2*i+1;
     S+=j;
    }
    线性乘法又可以进一步改进为加法:
    S=0;
    j=0;
    k=-1;
    for (i=1; i<=n; i++)
    {
     k+=2;
     j+=k;
     S+=j;
    }
    当然还可以对上面的循环变量进行交换以进一步提高效率。
    有关循环优化的最后一个课题是关于多重循环的组织问题。多重循环是需要加以有效地组织的,这可能

    与我们通常的理解相反,比知说,我们要旋转一幅图象,一个典型的二重循环可以完成这一任务:
    // ImageSre,lmageDst分别为原图象与目标图象
    // cosV,sinV分别旋转角的余、正弦值
    for (x=0; x<W; x++)  // W,H分别为原图象宽度和高度
     for (y=0; y<H; y++)
     {
      GetPixel(ImageSrc, x, y, color); // 取原图象一象素
      x’=x*cosV-y*sinV+x0;
      y’=x*sinV+y*cosV+y0;
      PutPixel(ImageDst, x’, y’, color);  // 置图象目标一象素
     }
    这一程序可进行多方面的优化,但无论怎样改造,上面的程序总存在一个先天的不足:数据的处理次序

    与存贮次序不一致,一幅图象,或者直观地说一个二维数组,在内存中总是逐行存放的,而在上面的处

    理中却是逐列进行的,这会有什么问题呢?首先,两者之间的不一致会导致程序在许多方面优化不下去,

    例如,我们可设计一个指针指向原图象的某一象素,要取下一象素时,只需将指针加1即可,而且,从第

    一个象素至最后一个象素都能按这一方式统一处理,而如果逐列处理,当前处理的象素与下一象素位置

    上相差太远,有时还需要跳来跳去,象素指针的这种统一位移关系就会被破坏,造成处理的低效;其次

    还有一个更严重、更隐蔽的问题。如果要处理的图象太大,在内存中不能一次放入,这就需要在内存与

    文件之间往复交换数据,当处理次序与存放次序不一致时,数据将会频繁地在内外存之间倒换,从而产

    生抖动现象,即系统忙于为程序的正常运行准备内存空间而不停顿地交换内外存数据,反而使得程序无

    法正常运行下去。如果我们在Windows上设计出一个产生抖动的程序,就会看到硬盘指示灯不断闪烁。如

    果出现这种情况,就要对你的程序仔细检查,看是否有抖动的情况存在。
     

    展开全文
  • 前言 对于提高 JavaScript 程序的性能这个问题,最简单同时也是很容易被忽视的方法就是学习如何正确编写高性能循环语句。...两个主要因素助于改善循环性能 —— 每次迭代完成的工作和迭代次数。 在下面的内容中,
  • 循环优化与多面体模型

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

    循环通常是数据并行应用的最密集计算段,因此循环优化直接影响性能。当面对嵌套循环时,分配给线程的计算粒度将直接影响性能。循环转换如Fission(循环裂变)与Fusion(循环融合)的嵌套式循环可促使并行化,并提高工作效率。

    本文就几种循环优化的方法与多面体模型的调度进行简要阐述(因为LZ已经被这些循环优化搞得痛不欲生了)。


    Loop fusion

    顾名思义,该变换令循环进行了融合。如图所示,原始代码是两个for循环,变化之后,对两个循环中 i、j 相同的范围进行了融合。
    在这里插入图片描述
    我们为了把该变换映射或者说调度到多面体模型中去,需要产生调度树。

    举例如下:
    在这里插入图片描述
    有这样一段用TC写的代码,语句S、T分别为循环语句。其融合操作表述如下:
    在这里插入图片描述
    Band 操作将S、T所对应的迭代向量进行了融合。


    Loop tiling

    Loop tiling/blocking 的意思是分块,可以将循环的迭代空间划分为更小的块,以帮助确保循环中使用的数据在重用之前一直保存在缓存中。循环迭代空间的划分导致将大数组划分为更小的块,从而将被访问的数组元素匹配到缓存大小中,增强缓存重用,消除缓存大小需求。

    平常的循环:

    for(i=0; i<N; ++i){
      ...
    }
    

    变换后的循环,拥有一个全新的 block 大小B:

    for(j=0; j<N; j+=B){
      for(i=j; i<min(N, j+B); ++i){
        ....
      }
    }
    

    更具体的例子:
    在这里插入图片描述
    下面是一个矩阵向量乘法的例子。有三个数组,每个数组有100个元素。代码没有将数组划分为更小的大小。

      int i, j, a[100][100], b[100], c[100];
      int n = 100;
      for (i = 0; i < n; i++) {
        c[i] = 0;
        for (j = 0; j < n; j++) {
          c[i] = c[i] + a[i][j] * b[j];
        }
      }
    

    当我们应用循环分块,使用2 * 2块,代码变为:

      int i, j, x, y, a[100][100], b[100], c[100];
      int n = 100;
      for (i = 0; i < n; i += 2) {
        c[i] = 0;
        c[i + 1] = 0;
        for (j = 0; j < n; j += 2) {
          for (x = i; x < min(i + 2, n); x++) {
            for (y = j; y < min(j + 2, n); y++) {
              c[x] = c[x] + a[x][y] * b[y];
            }
          }
        }
      }
    

    原来的循环迭代空间n×n。数组的访问块(i, j)也是n×n。当n过大和机器的缓存容量太小,访问数组元素的循环迭代(例如,i = 1, j = 1到n)可能交叉的高速缓存线路,导致缓存丢失。

    展开全文
  • 介绍了Javascript中的循环优化需要的朋友可以参考一下
  • js循环优化

    2016-03-16 11:24:39
    for-in:枚举任何对象的命名属性,包括实例属性和原型链继承的属性,相对上面三个循环慢,若需迭代一个有限已知的属性列表,其他循环更快 循环需要注意影响性能的地方: - 迭代次数 - 迭代处理 性能优化: - ...
    • for
    • do-while
    • while
    • for-in:枚举任何对象的命名属性,包括实例属性和原型链继承的属性,相对上面三个循环慢,若需迭代一个有限已知的属性列表,其他循环更快

    循环需要注意影响性能的地方:
    - 迭代次数
    - 迭代处理
    性能优化:
    - 缓存数组长度
    - 倒序循环,控制条件与0比较,相当于控制条件与true比较,非零数字自动强制转换为true
    - 减少迭代次数,达夫设备,在一次迭代中执行多次迭代操作

    var iterations = Math.floor(items.length / 8),
    startAt = items.length % 8,
    i = 0;
    do {
    switch(startAt){
    case 0: process(items[i++]);
    case 7: process(items[i++]);
    case 6: process(items[i++]);
    case 5: process(items[i++]);
    case 4: process(items[i++]);
    case 3: process(items[i++]);
    case 2: process(items[i++]);
    case 1: process(items[i++]);
    }
    startAt = 0;
    } while (--iterations);
    var i = items.length % 8;
    while(i){
    process(items[i--]);
    }
    i = Math.floor(items.length / 8);
    while(i){
    process(items[i--]);
    process(items[i--]);
    process(items[i--]);
    process(items[i--]);
    process(items[i--]);
    process(items[i--]);
    process(items[i--]);
    process(items[i--]);
    }

    js数组的forEach,遍历一个数组的所有成员,并在每个成员上执行一个函数,每个元素上执行的函数作为forEach的参数传入进去,因为每个数组要关联额外的函数调用,造成速度慢

    items.forEach(function(value, index, array){
    process(value);
    });
    展开全文
  • 编译优化之 - 通用循环优化

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

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

    千次阅读 2019-05-18 16:22:24
    循环是我们在写代码时经常用到的一种结构,而往往在考虑性能优化时,循环优化能带来很大的收益,特别是当我们不得不循环多次时,如果没对性能进行优化,那毫无疑问会带来性能的负担。 循环的类型 1.for循环 for...
  • java for循环优化

    千次阅读 2018-02-07 14:31:34
    1.嵌套循环中,应把数据级小的放在外面,数量级大的放在里面。 for (int i = 0; i 10 ; i++) {   for (int j = 0; j 10000000; j++) {     }  }  外大内小耗时:200192114...
  • 双重大数组循环优化

    千次阅读 2018-03-04 19:19:19
    双重大数组循环优化 一、前言 这几天发现服务在凌晨时容易报警,持续半个小时才正常,第二天分析日志和检查代码发现,一个过滤黑白名单的操作,其中黑名单的数据39万,白名单数据30万,然后处理的数据也80...
  • 多重循环性能优化

    千次阅读 2018-12-19 09:16:41
    优化后的多重for循环可以提升大半的效率。 方法 一、实例化变量尽量放在for循环体外,只实例化一次。 二、普通变量改为寄存器变量,如i++改为++i。前置递增运算避免了不必要的工作,它把值加1后直接返回改变了运算...
  • 这种方式就是把循环展开,据说可以提高性能,但测试效果不明显,在谷歌50中展开反倒变慢了,IE10这种变快了。看来实际使用中中还是需要测试测试代码: function doProcess(value1, value2) { return value1 + value...
  • C语言常规优化策略——循环优化

    千次阅读 2007-11-16 08:34:00
    C语言常规优化策略3 循环优化提高程序效率的核心是对影响代码执行速度的关键程序段进行优化。在任何程序中,最影响代码速度的往往是循环语句,特别是多层嵌套的循环语句。因此,掌握循环优化的各种实用技术是提高...
  • 多重for循环优化,提升运行效率

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

    千次阅读 2012-04-01 11:15:20
    对FOR循环优化心得 分类: DM642 优化 2009-09-14 17:20 365人阅读 评论(1) 收藏 举报 在程序中经常用到FOR循环,当一些算法实时性要求非常高时,对FOR循环的优化有时可以带来意想不到的收获...
  • C语言优化实例:多层循环优化

    千次阅读 2014-05-11 14:29:32
    对于多层循环优化有两种方式: 一是尽量将多层循环从逻辑上改为一层循环,如果可行的话。比如将二层循环改为一层循环优化前的代码: for (int i = 0; i {  for (int j = 0; j  sum += data[i][j]; }...
  • 为了进行循环优化,首先需要确定的是程序流图中哪些基本块构成一个循环。按照结构程序设计思想,程序员在编程时应使用高级语言所提供的结构性的循环语句来编写循环。而由高级语言的循环语句所形成的循环,是不难找出...
  • J2ME优化——for循环优化

    千次阅读 2005-09-08 15:58:00
    这里我主要和大家一起讨论for循环优化情况,主要讨论循环的变量条件使用递增和递减的差距,下面让我们来看这段代码。 package Optimize; import javax.microedition.midlet.MIDlet;import javax.microedition....
  • Android launcher 循环优化

    千次阅读 2011-12-11 10:52:18
    尤其是在临界切换时,壁纸的突然跳跃,朋友手机上的360桌面也这个问题,于是琢磨能不能在看懂的基础上进行一些优化: 壁纸的移动和变化主要是由系统android.app.WallpaperManager来维护,应用要控制壁纸只需要2个...
  • Java代码循环优化

    2008-10-30 09:41:31
    循环优化设计包括数字比较尽量和0比较;尽量把异常捕获写在循环外面;尽量不要在循环内调用方法等等
  • for循环代码优化

    2020-08-04 14:56:49
    今天就来说一下java代码优化的事情,今天主要聊一下对于for(while等同理)循环优化,它作为三大结构之一的循环,在我们编写代码的时候会经常用到。循环结构让我们操作数组、集合和其他一些规律的事物变得更加的...
  • C++ For循环优化

    2010-07-22 19:01:58
    C++循环冒泡法优化 在看到for循环冒泡排序(c++) 后 再次优化了一下,它的程序不能运行,我运行优化的成功了,对初学者理解很大帮助(还有注释)
  • 多层for循环优化

    千次阅读 2019-05-12 13:33:51
    1.6.1 找出最大周长的三角形 /*可以用穷举找出最长,三重循环。*/ for (i = 0; i ;++i) { for (j = i + 1; j ; ++j) { for (k = j + 1; k ; ++k) { len = b[i] + b[j] + b[k]; m
  • JS之for循环优化

    千次阅读 2016-03-25 16:08:50
    众所周知Js中的循环大致可以分为4中:  1.for循环  Javascript代码  for(var i=0;i  //循环主题  }  其中for循环是最常见的循环结构,由四部分组成:初始化、前测条件、后执行体、循环体。当代码运行...
  • HLS for循环优化 dataflow_疑问

    千次阅读 2020-03-03 23:08:11
    数据流优化就是在三个循环之间插入 Channel(可以是 Ping-pong RAM、FIFO 或 Register)。 通过配置数据流间的channel 选择pp RAM 或者FIFO Reg 不能直接进行dataflow的代码形式 Single-produ...
  • 在系统性能优化的时候循环和字符串处理一直是非常值得注意的地方。从心态上我们一定不能把自己的眼界放在十次或者是百次循环的层次上,也不能把自己要处理的字符串当做是十个二十个字符。每次遇到循环都要假定这个...
  • HLS:for循环优化

    千次阅读 2019-03-18 10:11:45
    loop trip count :循环执行了几次 loop interation latency :循环一次用了几个cycle loop interation latency(Loop II) :两次循环直接间隔了几个cycle loop latency:整个for循环的latency ...
  • 我打算测试多线程情况下一个long数值在++的时候是否会多线程问题,代码如下(jdk版本1.7.0_07): public class A { private long value = 0; public long getValue() { return value; } public ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 496,824
精华内容 198,729
关键字:

循环优化主要包括哪些