循环求和中的代码优化

在今天早上嵌入式课上的课前演示中,我提到了循环求和中的优化(其实那只是前一天我网上搜索做准备时无意碰到的)。演示中我举的例程如下:

int sum = 0;
for (int i = 0; i < 100; i++)
{
    sum += array[i];
}
//*********我是分割线****************************
int sum1 = 0, sum2 = 0;
for (int i = 0; i < 100; i += 2)
{
    sum1 += array[i];
    sum2 += array[i + 1];
}

int sum = sum1 + sum2;

当时在网上看到的结论是,第二种方法更优,原因有二:一是循环体中两个不相关的运算可以得到并行处理,减少运行时间;二是循环次数(从汇编的层次上讲就是条件跳转),其次数减少,因为条件跳转只有到最后一刻才知道代码会跳往何处。

演示完后,被老师问到,第二种方法能得到多大的优化,你测试过这代码吗?

悻悻地回答,没有。

于是回来之后我用更大的循环次数去测试验证了一下,代码一如下:

#include <windows.h>
#include <cstdio>
int main()
{
    DWORD start_time,end_time;
    int sum,i;

    start_time=GetTickCount();
    sum=0;
    for(i=0;i<1000000000;i++)
        sum+=i;
    end_time=GetTickCount();
    printf("%d\n",end_time-start_time);

    sum=0;
    int sum2=0,sum3=0;
    start_time=GetTickCount();
    for(int i=0;i<1000000000;i+=2)
        sum2+=i,sum3+=i+1;
    sum=sum2+sum3;
    end_time=GetTickCount();
    printf("%d\n",end_time-start_time);
}

运行结果:

5594

3328

由此可见,第二种方法确实能得到可观的性能优化。那么,现在剩下的问题是,到底是第一个原因起的作用大,还是第二个原因?

我把第二种方法的代码修改了,代码二如下:

    sum=0;
    start_time=GetTickCount();
    for(int i=0;i<1000000000;i+=2)
        sum+=i+i+1;
    end_time=GetTickCount();
    printf("%d\n",end_time-start_time);

运行结果:

5422

2953

经常多次测试表明,代码二确实比代码一里的第二种方法明显快上一点。因此,我个人感觉其中没有用到并行处理优化。也就是说,在特定的情况下,通过减少条件跳转次数,可以获得可观的性能优化。

下面我尝试进行-O编译优化。结果如下:

-O1优化居然能减少这么多时间!不过可能是这段代码逻辑太简单了。另外不知道为什么-O2优化后的运行结果不正常。。。有知道原因的童鞋请多多指教!

循环求和中的代码优化

时间: 2024-10-26 16:21:12

循环求和中的代码优化的相关文章

用angularjs在循环遍历中绑定ng-model(转载---CSDN博客 )

用angularjs在循环遍历中绑定ng-model CSDN博客 原文  http://blog.csdn.net/chen2991101/article/details/19764263 angularjs的双向绑定非常的好用,当修改了一个地方的值后另外一个地方也同步修改了,如果用平时的js来写的话需要写很多代码,但是用了angularjs后只需要几行代码就能轻松搞定. 想做一个类似于淘宝的改价的功能,就是当用户拍下了宝贝后卖家给你调价的那个功能,界面就像这样: 当修改了折扣或者直接填写了优

Oracle游标-循环查询表中数据(表名),并执行

Oralce 表中存有一个字段,该字段存储表名,要把该表中的所有表名查询出来(即表名结果集),且执行结果集from 表名结果集: declare v_ccount varchar2(100); --定义一个游标变量 cursor c_job is --查询该表中的所有表名 select tablename from tbname; c_row c_job%rowtype; begin --循环待处理数据,即以上查出的结果集 for c_row in c_job loop ---执行语句 from

循环语句中的else

1. 循环语句中的else是什么意思? 循环语句一般是用来遍历一组值的过程, else就是再最后补一下刀, 也就是说当for或while正常执行结束之后, 会再次执行一次else里面的内容. 样例代码: # -.- coding:utf-8 -.- __author__ = 'zt' for i in range(5):     print i else:     print "这里是else输出:", i+1           输出结果: 0 1 2 3 4 这里是else输出: 

JAVA性能调优-在循环条件中不要使用表达式

1.JAVA性能调优-在循环条件中不要使用表达式 我们在学习JAVA性能调优的时候,经常能看到这一的一段话:在不做编译优化的情况下,在循环中,循环条件会被反复计算,如果不使用复杂表达式,而使循环条件值不变的话,程序将会运行的更快. import java.util.vector; class cel { void method(vector vector) { for (int i= 0; i < vector.size (); i++)  //violation ; //... } } 更正:

循环repeater中的textbox,相加

循环repeater中textbox的值,并相加 var num = 0; function txt_change() { $.each($("input:text[id*='txtgs']"), function (index, item) { $(item).bind("keyup", function () { $.each($("input:text[id*='txtgs']"), function (index, item) { if

java代码:用for循环求和,求偶数和,求奇数和,打印水仙花数,统计水仙花数

用for循环求和,求偶数和,求奇数和,打印水仙花数,统计水仙花数package loop; public class For1 {public static void main(String[] args) {int sum=0;for(int x=0;x<=100;x++) {sum=sum+x;}System.out.println("100以内(含100)整数和:"+sum);System.out.println("------------------------

循环语句中break 与 continue的区别

循环语句中break 与 continue的区别 总结: 1 break; while循环break是用于永久终止循环.即不执行本次循环中break后面的语句,直接跳出循环. 2continue; while循环continue是用于终止本次循环.即本次循环中continue后面的代码不执行,进行下一次循环的入口判断. #include<stdio.h> //break; int main() { int i = 0; while (i <= 10) { if (i == 5) brea

详解javaweb中jstl如何循环List中的Map数据_java - JAVA

文章来源:嗨学网 敏而好学论坛www.piaodoo.com 欢迎大家相互学习 详解javaweb中jstl如何循环List中的Map数据 第一种方式: 1:后台代码(测试) List<Map<String, Object>> list = new ArrayList<Map<String,Object>>(); Map<String, Object> map = null; for (int i = 0; i < 4; i++) { ma

题目:返回一个一维循环数组中最大子数组的和

#include <iostream> #include <ctime> #define N 10 using namespace std; int maxxunhuan(int array[N] , int n){ int i,j = 0,m,c = 0; int sum = array[0],b = 0,max = 0; for(j = 0;j < n;j++){ b = 0; for(i = j;i < n;i++){ if(i < n-1){ if(b &