代码优化

记一次代码优化

末鹿安然 提交于 2020-11-03 11:34:08
题目选择:不定方程的非负整数解解。 问题描述:问方程 x+2y+5z=n, 对于特定输入的 n ( n<=1000000 ),输出其大于的整数解的个数。其时间限制是为: 1000ms 。 选择原因:选择此题主要是由于自己实际作此题过程中,遇到了很多问题,这篇报告主要是来写我对于这些问题的解决,与对代码的不断优化。 解题过程: 这个问题非常简单,是的,非常简单,只要一个枚举就能解决,而我为啥还要选择这个问题来写报告了,因为当我改了多次代码系统才通过我写的代码,由于我下了狠心,一定要尽自己最大的努力把它写的最好,写的运行速度最快,甚至举一反三的将这个问题扩散到更广。 我拿到这个问题,想都没想就写了如下的代码: #include <stdio.h> void jieshu(int n) { int i,j,k,g; for(i=0;i<=n;i++) for(j=0;j<=n/2;j++) for(k=0;k<=n/5;k++) { if(i+2*j+5*k==n) g++; } printf("%d",g); } int main() { int t,n; while(~scanf("%d",&t)) { while(t--) { scanf("%d",&n) jieshu(n); } } return 0; } 这就是一个暴力枚举法,的确对于很小的 n ,结果完全没有问题

C\\C++代码优化的27个建议

喜你入骨 提交于 2020-04-06 11:52:34
1. 记住 阿姆达尔定律 : funccost 是函数func运行时间百分比, funcspeedup 是你优化函数的运行的系数。 所以,如果你优化了函数 TriangleIntersect 执行40%的运行时间,使它运行快了近两倍,而你的程序会运行快25%。 这意味着不经常使用的代码不需要做较多优化考虑(或者完全不优化)。 这里有句俗语:让经常执行的路径运行更加高效,而运行稀少的路径正确运行。 2. 代码先保证正确,然后再考虑优化 这并不意味着用8周时间写一个全功能的射线追踪算法,然后用8周时间去优化它。 分多步来做性能优化。 先写正确的代码,当你意识到这个函数可能会被经常调用,进行明显的优化。 然后再寻找算法的瓶颈,并解决(通过优化或者改进算法)。通常,改进算法能显著地改进瓶颈——也许是采用一个你还没有预想到的方法。所有频繁调用的函数,都需要优化。 3. 我所了解的那些写出非常高效代码的人说,他们优化代码的时间,是写代码时间的两倍。 4.跳转和分支执行代价高,如果可能,尽量少用。 函数调用需要两次跳转,外加栈内存操作。 优先使用迭代而不是递归。 使用内联函数处理短小的函数来消除函数调用开销。 将循环内的函数调用移动到循环外(例如,将 for(i=0;i <100;i++) DoSomething(); 改为 DoSomething() { for(i=0;i <100;i++)

if-else代码优化的八种方案

孤街醉人 提交于 2020-04-06 11:01:25
if-else代码优化的八种方案 if-else代码优化的八种方案 前言 代码中如果if-else比较多,阅读起来比较困难,维护起来也比较困难,很容易出bug,接下来,本文将介绍优化if-else代码的八种方案。 优化方案一:提前return,去除不必要的else 如果if-else代码块包含return语句,可以考虑通过提前return,把多余else干掉,使代码更加优雅。 优化前: if(condition){ //doSomething }else{ return ; } 优化后: if(!condition){ return ; } //doSomething 优化方案二:使用条件三目运算符 使用条件三目运算符可以简化某些if-else,使代码更加简洁,更具有可读性。 优化前: int price ; if(condition){ price = 80; }else{ price = 100; } 优化后: int price = condition?80:100; 优化方案三:使用枚举 在某些时候,使用枚举也可以优化if-else逻辑分支,按个人理解,它也可以看做一种 表驱动方法 。 优化前: String OrderStatusDes; if(orderStatus==0){ OrderStatusDes ="订单未支付"; }else if(OrderStatus=

C\\C++代码优化的27个建议

这一生的挚爱 提交于 2020-04-06 10:35:18
1. 记住 阿姆达尔定律 : func cost 是函数func运行时间百分比, func speedup 是你优化函数的运行的系数。 所以,如果你优化了函数 TriangleIntersect 执行40%的运行时间,使它运行快了近两倍,而你的程序会运行快25%。 这意味着不经常使用的代码不需要做较多优化考虑(或者完全不优化)。 这里有句俗语:让经常执行的路径运行更加高效,而运行稀少的路径正确运行。 2. 代码先保证正确,然后再考虑优化 这并不意味着用8周时间写一个全功能的射线追踪算法,然后用8周时间去优化它。 分多步来做性能优化。 先写正确的代码,当你意识到这个函数可能会被经常调用,进行明显的优化。 然后再寻找算法的瓶颈,并解决(通过优化或者改进算法)。通常,改进算法能显著地改进瓶颈——也许是采用一个你还没有预想到的方法。所有频繁调用的函数,都需要优化。 3. 我所了解的那些写出非常高效代码的人说,他们优化代码的时间,是写代码时间的两倍。 4.跳转和分支执行代价高,如果可能,尽量少用。 函数调用需要两次跳转,外加栈内存操作。 优先使用迭代而不是递归。 使用内联函数处理短小的函数来消除函数调用开销。 将循环内的函数调用移动到循环外(例如,将 for(i=0;i <100;i++) DoSomething(); 改为 DoSomething() { for(i=0;i <100;i+

KEIL C51代码优化详细分析

狂风中的少年 提交于 2020-04-06 07:55:19
阅读了《 单片机 与 嵌入式 系统应用》2005年第10期杂志《经验交流》栏目的一篇文章《Keil C51 对同一端口的连续读取方法》(原文)后,笔者认为该文并未就此问题进行深入准确的分析 文章中提到的两种解决方法并不直接和简单。笔者认为这并非是Keil C51中不能处理对一个端口进行连续读写的问题,而是对Kei1 C51的使用不够熟悉和设计不够细致的问题,因此特撰写本文。 本文中对原文提到的问题,提出了三种不同于原文的解决方法。每种方法都比原文中提到的方法更直接和简单,设计也更规范。(无意批评,请原文作者见谅) 1 问题回顾和分析 原文中提到:在实际工作中遇到对同一端口反复连续读取,Keil C51编译并未达到预期的结果。原文作者对C编译出来的汇编程序进行分析发现,对同一端口的第二次读取语句并未被编译。但可惜原文作者并未分析没有被编译的原因,而是匆忙地采用一些不太规范的方法试验出了两种解决办法。 对此问题,翻阅Keil C51的手册很容易发现:KeilC51的编译器有一个优化设置,不同的优化设置,会产生不同的编译结果。一般情况缺省编译优化设置被设定为8级优化,实际最高可设定为9级优化: 1. Dead code elimination。 2.Data overlaying。 3.Peephole optimization。 4.Register variables。 5

2.2优化编译器的能力和局限性

老子叫甜甜 提交于 2020-04-06 07:17:35
写程序最主要的目标是使他在所有的可能的情况下都能正确工作。程序应该写出清晰简单的代码,主要为了给后期维护,起作用;但常常我们在程序的简单性,维护性,与程序的运行速度进行权衡; 高效的程序需要几类活动: (1)必须选择一组合适的算法和数据结构; (2)必须编写出编译器能够优化以转换成高效可执行的源代码,因此理解优化编译器的能力和局限性很重要,因此程序即使是很小的变动,会引起编译器优化方式很大的变化;因此程序员经常能够使编译器更容易产生高效代码的方式来编写他们的程序,对于C语言的指针,就编译器已经很难优化了; (3)并发编程,利用多处理器和多核的某种组合并行的计算; 现代编译器使用复杂精细的算法来确定一个程序中计算的是什么值,以及它们是如何使用的,然后利用一些机会来简化表达式,在几个不同的地方使用用一个计算,降低给定计算的执行次数;GCC编译器提供优化级别的控制,级别越高,程序的规模可能会提高,调试困难会提高;低级别的优化高效的C代码,要比高级别的优化初级的C代码性能要高; 要是编译器安全的优化,程序员必须花大力气编写编译器可以转换成有效的代码,举例如下: (1)*x += * y; *x += *y; 与(2)*x += 2 * *y; 这两个代码片段似乎有相同的行为;(2)要快一点,涉及3次存储器引用,而(1)涉及6次存储器引用,但是如果考虑*x = *y,则(1)会增加4倍的值

【CSAPP笔记】10. 代码优化

谁说我不能喝 提交于 2020-04-06 05:48:09
写程序的主要目标是使它在所有可能的情况下都能正确运行(bug free),一个运行得很快但有 bug 的程序是毫无用处的。在 bug free 的基础上,程序员必须写出清晰简洁的代码,这样做是为了今后检查代码或修改代码时,其他人能够读懂和理解代码。另一方面,让程序运行得更快也是一个很重要的考虑因素。不过,程序获得最大加速比的时候,是它第一次运行起来的时候。 在提到优化程序性能时(Code optimization),我们往往会想到算法与数据结构中的一个概念——复杂度。事实上,除了算法复杂度之外,仍然有许多的代码书写小细节可以改进性能表现。不过,编写高效的程序,第一个考虑的还是选择一组合适的算法与数据结构,因为算法复杂度影响还是相当大的,而且通常比其他常量因素更重要。第二点,我们必须写出编译器能够有效优化以转换成高效可执行代码的源代码。对于第二点,理解程序是如何被编译和执行、理解处理器和存储器系统是如何运作的、理解编译器优化的局限性是很重要的。在程序开发过程中,程序员必须在实现和维护程序的简单性与它的运行速度之间做出权衡,也就是在尽量不破坏程序的模块化和通用性的前提下,做到对代码性能的优化。 即使是最好的编译器也受到 妨碍优化的因素 (optimization blocker)的阻碍,程序员必须编写容易优化的代码,来 帮助 编译器(很让人眼界一新的观点)。研究程序的汇编代码

KEIL中程序优化说明

时间秒杀一切 提交于 2020-04-06 04:08:31
优化级别说明(仅供参考) : 则其中的 Code Optimization 栏就是用来设置 C51 的优化级别。共有 9 个优化 级别(书上这么写的) ,高优化级别中包含了前面所有的优化级别。现将各个级 别说明如下: 0 级优化: 1 、 常数折叠:只要有可能,编译器就执行将表达式化为常数数字的计算,其中 包括运行地址的计算。 2 、 简单访问优化:对 8051 系统的内部数据和位地址进行访问优化。 3 、 跳转优化:编译器总是将跳转延至最终目标上,因此跳转到跳转之间的命令 被删除。 1 级优化: 1 、 死码消除:无用的代码段被消除。 2 、 跳转否决:根据一个测试回溯,条件跳转被仔细检查,以决定是否能够简化 或删除。 2 级优化: 1 、 数据覆盖:适于静态覆盖的数据和位段被鉴别并标记出来。连接定位器 BL51 通过对全局数据流的分析,选择可静态覆盖的段。 3 级优化: 1 、 “ 窥孔 ” 优化:将冗余的 MOV 命令去掉,包括不必要的从存储器装入对象及 装入常数的操作。另外如果能节省存储空间或者程序执行时间,复杂操作将由简 单操作所代替。 4 级优化: 1 、 寄存器变量:使自动变量和函数参数尽可能位于工作寄存器中,只要有可能, 将不为这些变量保留数据存储器空间。 2 、扩展访问优化:来自 IDATA 、 XDATA 、 PDATA 和 CODE 区域的变量直接包

C语言编程优化运行速度

混江龙づ霸主 提交于 2020-04-06 04:02:18
1、选择合适的算法和数据结构 选择一种合适的数据结构很重要,如果在一堆随机存放的数中使用了大量的插入和删除指令,那使用链表要快得多。数组与指针语句具有十分密切的关系,一般来说,指针比较灵活简洁,而数组则比较直观,容易理解。对于大部分的编译器,使用指针比使用数组生成的代码更短,执行效率更高。 在许多种情况下,可以用指针运算代替数组索引,这样做常常能产生又快又短的代码。与数组索引相比,指针一般能使代码速度更快,占用空间更少。使用多维数组时差异更明显。下面的代码作用是相同的,但是效率不一样。 数组索引 指针运算 For(;;){ p=array A=array[t++]; for(;;){ a=*(p++); 。。。。。。。。。 。。。。。。 } } 指针方法的优点是, array 的地址每次装入地址 p 后,在每次循环中只需对 p 增量操作。在数组索引方法中,每次循环中都必须根据 t 值求数组下标的复杂运算。 2、使用尽量小的数据类型 能够使用字符型 (char) 定义的变量,就不要使用整型 (int) 变量来定义;能够使用整型变量定义的变量就不要用长整型 (long int) ,能不使用浮点型 (float) 变量就不要使用浮点型变量。当然,在定义变量后不要超过变量的作用范围,如果超过变量的范围赋值, C 编译器并不报错,但程序运行结果却错了,而且这样的错误很难发现。 在

c语言中的代码优化《转》

痴心易碎 提交于 2020-04-06 03:03:44
在性能优化方面永远注意80-20原则,即20%的程序消耗了80%的运行时间,因而我们要改进效率,最主要是考虑改进那20%的代码。不要优化程序中开销不大的那80%,这是劳而无功的。 第一招:以空间换时间   计算机程序中最大的矛盾是空间和时间的矛盾,那么,从这个角度出发逆向思维来考虑程序的效率问题,我们就有了解决问题的第1招--以空间换时间。比如说字符串的赋值: 方法A:通常的办法 #define LEN 32 char string1 [LEN]; memset (string1,0,LEN); strcpy (string1,"This is a example!!"); 方法B: const char string2[LEN] ="This is a example!"; char * cp; cp = string2 使用的时候可以直接用指针来操作。 从上面的例子可以看出,A和B的效率是不能比的。在同样的存储空间下,B直接使用指针就可以操作了,而A需要调用两个字符函数才能完成。B的缺点在于灵活 性没有A好。在需要频繁更改一个字符串内容的时候,A具有更好的灵活性;如果采用方法B,则需要预存许多字符串,虽然占用了大量的内存,但是获得了程序执 行的高效率。 如果系统的实时性要求很高,内存还有一些,那我推荐你使用该招数。 第二招: 使用宏而不是函数。   这也是第一招的变招