码迷,mamicode.com
首页 > 其他好文 > 详细

常数优化

时间:2019-08-19 20:46:42      阅读:79      评论:0      收藏:0      [点我收藏+]

标签:目的   查询   寄存器   str   了解   一点   etc   需要   记忆化搜索   

关于考场上优化代码常数的一些小技巧......

常数优化

  1. 读入优化

优化程序不如常数,优化常数不如优化\(IO\)

当一道题目的输入量开始变大时,这就意味我们要开始优化\(IO\)了。

优化了一道题的读入后,在读入较大的情况系,大概可以快个\(100-200ms\)左右。

代码如下:

inline int Read(void) {
    int res=0,f=1;
    char c;
    while(c=getchar(),c<48||c>57)if(c=='-')f=0;
    do res=(res<<3)+(res<<1)+(c^48);
    while(c=getchar(),c>=48&&c<=57);
    return f?res:-res;
}

这只是最最普通的读入优化,大神版的读优手写了\(getchar\),速度快到飞起:

代码如下:

inline char G1() {
    static const int LEN=2000005;
    static char U[LEN],*T=U,*E=U;
    if(T==E)T=U,E=U+fread(U,1,LEN,stdin);
    return T==E?EOF:*T++;
}
inline int Read(void) {
    int res=0,f=1;
    char c;
    while(c=G1(),c<48||c>57)if(c=='-')f=0;
    do res=(res<<3)+(res<<1)+(c^48);
    while(c=G1(),c>=48&&c<=57);
    return f?res:-res;
}
  1. ++i

从所周知,循环通常有两种写法:

for(int i=1;i<=n;i++);
for(int i=1;i<=n;++i);

而事实上,下面一行的代码比上面一行的代码快了不止一点,原因是:

\(++i\)是先改变i的值即加1后再使用i的值,而\(i++\)是先使用i的值在改变它的值即加。

由此,在循环中使用\(++i\)会比\(i++\)快一些。

  1. register

众所周知,\(register\)是一个好东西,他利用了寄存器读入以及运行比普通要快的原理,请求让编译器将变量直接放入寄存器里面,以提高读取速度;

用法:在需要多次使用的变量前加上\(register\)即可。

register int a;

不过,需要注意的是由于寄存器太小,通常只能寄存\(8\)个变量,所以在一份代码中我们用\(register\)修饰过的变量不能超过\(8\)个。

register关键字请求让编译器将变量a直接放入寄存器里面,以提高读取速度,在C语言中register关键字修饰的变量不可以被取地址,但是c++中进行了优化。

  1. inline

在c/c++中,为了解决一些频繁调用的小函数大量消耗栈空间(栈内存)的问题,特别的引入了inline修饰符,表示为内联函数,栈空间就是指放置程序的局部数据(也就是函数内数据)的内存空间。在系统下,栈空间是有限的,假如频繁大量的使用就会造成因栈空间不足而导致程序出错的问题,如,函数的死循环递归调用的最终结果就是导致栈内存空间枯竭。

\(inline\)的函数不能是递归函数,同时,当我们加入\(inline\)修饰时,我们并不能确定编译器是否将其内联,事实上决定了函数是否内联还是编译器本身,\(qwq\)

也就是说,一个函数是否内联是看编译器心情的。。。。

  1. 利用指针优化和取址优化

在考试以及比赛中,我们常常会需要查询一段多维数组的值,以及修改一段多维数组的值。

这时候,我们可以利用指针进行一些优化,以减少常数。

例如,我们需要在\(A[i][1]-A[i][n]\)中找一个最小值,我们可以这样打:

int Ans=1e9;
int *p=A[i];
for(int i=1;i<=n;++i)Ans=min(Ans,*++p);
return Ans;

这样,我们优化了查找的常数,事实上,在数组维度很大的情况下,运行时间和内存往往会减小很多。

同理利用取址来优化常数也是一样的,在记忆化搜索时,我们常常需要调用和修改一个数组的值:

int dfs(int x){
    if(~dp[x])return dp[x];
    dp[x]++;
    return dp[x];
}

该成这样会快很多:

int dfs(int x){
    int &t=dp[x];
    if(~t)return t;
    t++;
    return t;
}

以上内容帮助我们优化了一部分常数,

常数优化

标签:目的   查询   寄存器   str   了解   一点   etc   需要   记忆化搜索   

原文地址:https://www.cnblogs.com/dsjkafdsaf/p/11379266.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!