编程语言中运算符的运算效率

编程语言中运算符的运算效率

版权声明:本文为CSDN博主「白萝卜blb」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/morgerton/article/details/64918560
原文链接:https://blog.csdn.net/morgerton/article/details/64918560

        在使用各种计算机语言编程时,同一种问题可能有好几种解决方案,比如在使用取余运算符时,‘%’操作符和‘ - ’操作符其实使用样的效果,结果都一样,用那种效率比较好?

        摘自:

        http://wenku.baidu.com/link?url=B89DssVNk7J3hGvkt97JU_50kQu-qn6aUdpeUd2dzh2hTBeUt-b6oLH44K-bRah-g95dhH-zzBwkdxioX6jgwXaEmUPczatrnsS_flzEYS_

        我们就从代码细节与算法设计两方面,比较不同程序执行时间的异同,从而选择其中较优的算法,提高程序运行效率。

        本试验所采用的环境是: CPU Celeron 3.06GHz,内存248M,操作系统Windows XP SP2,程序语言C。编译环境Dev-c++。以下称为1号机。配置略好于NOIP标准测试机CPU 2.0GHz。

  一、基本运算的速度

   为了增强算法效率的计算准确性,我们采用重复试验20次取平均值的做法。每次试验运行100000000次。

  基本运行时间,是指在准备计算的运算复杂度之外,只包括循环控制变量的加减与比较所消耗的时间。要从实际运行时间中减去基本运行时间,才是这种

运算真正的运行时间,称为净运行时间。

#include<stdio.h> 

main() { 

 int i,j;    

 double a,b,sum=0;    

 for(j=0;j<20;j++)//此处为进行20次试验设置的循环   

    { //此处添加随机数产生     

 a=clock();//时间a      

     for(i=0;i<100000000;i++);

     //此处添加运算,执行100000000次i+1     

     b=clock();//时间b      

      printf("%lf\n",b-a);//输出两个时间的差值     

      sum+=b-a;//20次基本运算使用总时间   

     }     

     printf("ans = %lf",sum/20.0);//输出平均时间   

     getch(); 

}  

运行平均时间是:202.3ms。 

(1)赋值运算,净运行时间0.8ms,与基本运行时间202.3ms相比,可忽略不计,故以后将赋值运算作为基本运行时间的一部分,不予考虑。

(2)加法运算,产生随机数: x=rand();y=rand(); 循环内加法:t=x+y; 下面的各种简单运算只是更改运算符即可,不再写出代码。  

净运行时间41.45ms,即:在1s的时限中,共可进行 (1000-202.3)/ 41.45*10^8=1.9*10^9次加法运算,即:只通过循环、加法和赋值的运算次数不超过1.9*10^9.。而应用+=运算,与普通加法时间几乎相同,所以+=只是一种方便书写的方法,没有实质效果。同样的,各种自运算并不能提高效率。

(3)减法运算(x-y),净运行时间42.95ms,与加法运算基本相同。可见,在计算机内部实现中,把减法变成加法的求补码过程是较快的,而按位相加的过程占据了较多的时间,借用化学中的一句术语,可以称为整个运算的“速控步”。当然,这个“速控步”的运行速度受计算机本身制约,我们无法优化。在下面的算法设计中,还会遇到整个算法的“速控步”,针对这类情况,我们要对占用时间最多的步骤进行细心优化,减少常数级运算次数。

(4)乘法运算(x*y)  净运行时间58.25ms,明显比加减法要慢,但不像某些人想象的那样慢,至少速度大于加减法的1/2。所以在实际编程时,没有必要把两个或三个加法变成乘法,其实不如元素乘常数来得快。不必“谈乘色变”,实际乘法作为CPU的一种基本运算,速度还是很快的。以上四种运算速度都很快,比循环所需时间少很多,在普通的算法中,每个最内层循环约含有4-5个加、减、乘运算,故整个算法的运行时间约为循环本身所需时间的2倍。

(5)除法运算(x/y) 净运行时间1210.2ms,是四种常规运算中最慢的一种,耗时是加法的28倍,是乘法的21.5倍,确实如常人所说“慢几十倍”,一秒的时限内只能运行8.26*10^7次,不足一亿次,远大于循环时间。所以,在计算时应尽量避免除法,尤其是在对时间要求较高的内层循环,尽量不安排除法,如果整个循环中值不变,可以使用在循环外预处理并用一个变量记录,循环内再调用该变量的方法,可以大大提高程序运行效率。

6)取模运算(x mod y)  净运行时间1178.15ms,与除法运算速度几乎相当,都非常慢。

所以,取模运算也要尽量减少。在大数运算而只要求求得MOD N的值的题目中,应尽量利用数据类型的最大允许范围,在保证不超过MAXINT的前提下,尽量少执行MOD运算。例如在循环数组、循环队列的应用中,取模运算必不可少,这时优化运算便十分重要。可利用计数足够一定次数后再统一MOD,循环完后再MOD,使用中间变量记录MOD结果等方法减少次数。  在高精度计算中,许多人喜欢边运算边整理移位,从而在内层循环中有除、模运算各一次,效率极低。应该利用int的数据范围,先将计算结果保存至当前位,在各位的运算结束后再统一整理。


  确实存在算法符号效率的问题,但是现在再重新计算下,测试代码如下:


class TestSymbol
{
public static void main(String[] args) 
{
long source = 1345634571234556l;
long source_after = 1200000000000000l;


long length = 40;
long[] timeSub = new long[40];


for(int i = 0; i < 40; i++){
long start = System.currentTimeMillis();
long outCome = source / source_after;
long end = System.currentTimeMillis();
timeSub[i] = end - start;
System.out.println("result:" + timeSub[i] + ", start:" + start + ", end:" + end);
}


long result = 0;
for(int i = 0; i < timeSub.length; i++){
result = result + timeSub[i] / length;
}
System.out.println("% time sub result:" + result);


long[] timeSub_ = new long[40];


for(int i = 0; i < 40; i++){
long start = System.currentTimeMillis();
long outCome_ = source - source_after;
long end = System.currentTimeMillis();
timeSub_[i] = end - start;
System.out.println("result_:" + timeSub_[i] + ", start:" + start + ", end:" + end);
}


long result_ = 0;
for(int i = 0; i < timeSub.length; i++){
result_ = result_ + timeSub_[i] / length;
}
System.out.println("- time sub result:" + result_);


System.out.println("Hello World!");
}
}

代码大概的意思就是说取一个很大的long类型的数,依次执行‘-’和‘%’操作,求一下时间差的平均值,

结果看图:



后来我又分别试了*,/符号,发现执行结果都是这样。

  做这个测试的目的就是因为我做的东西里面需要高频,大量的操作,我把'%' 改成了'-'解决了一些问题,所以特意测试下,结论如下:

  在当前CPU这么NB的时代,这样执行是没有任何响应时间差别的,但是呢,如果持续的高频大量的操作,就会有问题了,比如一般的明显效率对比:- 肯定比 % 快,位操作肯定比 + ,-,*,/快,所以建议使用如果环境所迫,最好使用效率相对较高的运算符。





  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java经典编程源码例程,可以做为你的学习设计参考。 第1章 Java语言概述 1 实例001 输出“Hello World” 2 实例002 输出控制台传递的参数 2 实例003 输出由“*”组成的三角形 3 实例004 输出符号表情 5 第2章 Eclipse开发工具 6 实例005 下载并运行Eclipse工具 7 实例006 为Eclipse安装文包 8 实例007 使用Eclipse注释代码 10 实例008 使用Eclipse格式化代码 11 实例009 安装WindowBuilder插件 12 实例010 开发计算器界面 14 第3章 Java语言基础 15 实例011 输出错误信息与调试信息 16 实例012 从控制台接收输入字符 16 实例013 重定向输出流实现程序日志 17 实例014 自动类型转换与强制类型转换 19 实例015 加密可以这样简单(位运算) 20 实例016 用三元运算符判断奇数和偶数 21 实例017 不用乘法运算符实现2×16 22 实例018 实现两个变量的互换 (不借助第3个变量) 23 第4章 流程控制 25 实例019 判断某一年是否为闰年 26 实例020 验证登录信息的合法性 27 实例021 为新员工分配部门 28 实例022 用switch语句根据消费 金额计算折扣 29 实例023 判断用户输入月份的季节 31 实例024 使用while循环语句与自增 运算符循环遍历数组 33 实例025 使用for循环输出杨辉三角形 34 实例026 使用嵌套循环在控制台上 输出九九乘法表 35 实例027 使用while循环计算1+ 1/2!+1/3!…1/20! 36 实例028 使用for循环输出空心的菱形 38 实例029 终止循环体 39 实例030 循环体的过滤器 41 第5章 数组及其常用操作 43 实例031 获取一维数组的最小值 44 实例032 将二维数组的行列互换 45 实例033 利用数组随机抽取幸运观众 47 实例034 用数组设置JTable表格的 列名与列宽 49 实例035 使用按钮控件数组实现 计算器界面 51 实例036 通过复选框控件数组实现 添加多个复选框控件 52 实例037 使用选择排序法对数组排序 53 实例038 使用冒泡排序法对数组排序 55 实例039 使用快速排序法对数组排序 57 实例040 使用直接插入法对数组排序 59 实例041 使用sort()方法对数组排序 61 实例042 反转数组元素的顺序 63 第6章 面向对象入门 65 实例043 自定义图书类 66 实例044 温度单位转换工具 67 实例045 成员变量的默认初始化值 68 实例046 单例模式的应用 69 实例047 汉诺塔问题求解 70 实例048 编写同名的方法 71 实例049 构造方法的应用 72 实例050 统计图书的销售量 73 实例051 两只完全相同的宠物 74 实例052 重新计算对象的哈希码 76 实例053 使用字符串输出对象 77 实例054 Java对象的假克隆 78 实例055 Java对象的浅克隆 80 实例056 Java对象的深克隆 82 实例057 序列化与对象克隆 84 实例058 深克隆效率的比较 87 第7章 面向对象进阶 89 实例059 经理与员工的差异 90 实例060 重写父类的方法 92 实例061 计算几何图形的面积 93 实例062 简单的汽车销售商场 95 实例063 使用Comparable接口自定 义排序 96 实例064 策略模式的简单应用 98 实例065 适配器模式的简单应用 100 实例066 普通内部类的简单应用 102 实例067 局部内部类的简单应用 103 实例068 匿名内部类的简单应用 104 实例069 静态内部类的简单应用 105 实例070 实例化Class类的几种方式 107 实例071 查看类的声明 108 实例072 查看类的成员 110 实例073 查看内部类信息 112 实例074 动态设置类的私有域 113 实例075 动态调用类方法 115 实例076 动态实例化类 116 实例077 创建长度可变的数组 117 实例078 利用反射重写toString()方法 119 第8章 字符串与包装类 121 实例079 将数字格式化为货币字符串 122 实例080 货币金额大写格式 123 实例081 String类格式化当前日期 125 实例082 字符串大小写转换 1
### 回答1: 西门子PLC使用SCL编程手册是指在利用西门子PLC进行编程时所使用的一本技术手册,SCL即Structured Control Language(结构化控制语言)的缩写。SCL是一种基于文本的编程语言,它可以用于逻辑控制的程序编制,可以对PLC进行高级功能的编程和控制。 在西门子PLC使用SCL编程手册,我们可以学习和了解到各种SCL编程语言的语法、规则和特点。这个手册会详细介绍如何创建和编辑一个SCL程序,包括如何定义变量、定义函数、编写逻辑语句以及调用其他模块等。通过学习手册的示例和案例,我们可以了解到如何使用SCL语言实现各种逻辑控制功能。 通过使用SCL编程手册,我们可以高效地编写和调试PLC控制程序。SCL具有结构化编程语言的特点,它可以将程序模块化,通过调用函数和块,提高程序的可读性和可维护性。另外,SCL也可以与其他编程语言(如LAD、FBD等)进行联动编程,增强PLC的功能和灵活性。 在西门子PLC使用SCL编程手册,我们还可以了解到PLC的硬件配置和网络通信等相关知识。这些内容可以帮助我们更好地了解PLC系统的工作原理和性能特点,并能够根据实际应用的需要,合理地配置和优化PLC系统。 总之,西门子PLC使用SCL编程手册是一本有用的工具书,通过学习和实践,我们可以掌握SCL编程语言,以及利用PLC进行复杂逻辑控制的技术和方法。 ### 回答2: 西门子PLC使用SCL编程手册是为了帮助工程师和程序员能够更好地掌握和使用SCL(Structured Control Language)编程语言,该语言是西门子PLC系统的一种高级编程语言。 SCL编程手册提供了详细的SCL语法和语言规范,以及丰富的编程示例和实例,帮助用户理解和掌握SCL编程的基本概念和技巧。手册涵盖了从SCL程序的创建、编译、下载和运行,到变量声明、赋值、运算符使用、条件语句、循环结构等各个方面的详细内容,使用户能够熟练地使用SCL语言编写程序。 通过SCL编程手册,用户可以了解到如何使用SCL语言来实现PLC控制系统的各种功能和任务,如数字逻辑运算、数学运算、位操作、定时器和计数器控制等。手册还介绍了如何使用SCL语言来进行PLC数据通信、网络通信、故障诊断和系统调试等工作,使用户能够更好地利用SCL语言来解决实际工程遇到的问题。 除了基本的SCL语言知识,SCL编程手册还提供了丰富的应用示例和案例,包括控制某一具体工业场景下的设备、机器人、生产线等。这些案例能够帮助用户更好地理解和应用SCL编程,同时也为用户提供了一些实际工程可能遇到的解决方案。 总之,通过西门子PLC使用SCL编程手册,用户可以充分了解和掌握SCL编程语言,从而更好地应用于PLC控制系统,解决实际工程的各种问题,提高工程效率和质量。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值