1. 程式人生 > >卡常數大法好!

卡常數大法好!

保存 下一條 最快 else inline block ram comm font

咳咳咳……好東西 _(:зゝ∠)_ 轉自某位大佬 http://www.cnblogs.com/widerg/p/7353866.html

C++ Interesting卡常數

作為一名OIer,在Noip中卡(kǎ)常數可以說是必備技巧。在此總結一下我所知卡常數的神奇手法:

  1. IO優化
    • fread 和 fwrite ,如果還想再優化有mmap....(然而並不會用,好像也沒用。。。)
    • 讀入優化(這個非常重要!!!!!!!)
    inline int Read()
    {
        int x=0,f=1;char c=getchar();
        while(c>‘9‘||c<‘0‘) {if(c==‘-‘) f=-1;c=getchar();}
        while(c>=‘0‘&&c<=‘9‘) {x=x*10+c-‘0‘; c=getchar();}
        return x*f;
    }
    • 輸出優化好像用不到唉( ˇ?ˇ )
  2. inline
    在聲明函數之前寫上inline修飾符(就像上面Read()一樣),可以加快一下函數調用,但只能用於一些操作簡單的函數。涉及遞歸,大號的循環等很復雜的函數,編譯器會自動忽略inline。

  3. register
    在定義變量前寫上register修飾符,用於把變量放到CPU寄存器中,適用於一些使用頻繁的變量:

    register int n,m;

    寄存器空間有限,如果放得變量太多,多余變量就會被放到一般內存中;
    快,不是一般的快,快到什麽程度呢?:

    register int a=0;
    for(register int i=1;i<=999999999;i++)
    a++;
    int a=0;
    for(int i=1;i<=999999999;i++)
    a++;

    結果:
    優化:0.2826 second
    不優化:1.944 second
    恐怖啊!!!!

  4. 循環展開

    循環展開也許只是表面,在緩存和寄存器允許的情況下一條語句內大量的展開運算會刺激 CPU 並發(前提是你的 CPU 不是某 CPU)...

  5. 取模優化(僅O2)

    //設模數為 mod
    inline int inc(int x,int v,int mod){x+=v;return x>=mod?x-mod:x;}//代替取模+
    inline int dec(int x,int v,int mod){x-=v;return x<0?x+mod:x;}//代替取模-
  6. 前置 ++

    後置 ++ 需要保存臨時變量以返回之前的值,在 STL 中非常慢。事實上,int 的後置 ++ 在實測中也比前置 ++ 慢 0.5 倍左右(UOJ 上自定義測試)

  7. 不要開bool,所有bool改成char,int是最快的(原因不明)。

  8. if()else語句比()?():()語句要慢,逗號運算符比分號運算符要快。

  9. 數據結構用指針代替數組(個人覺得無關緊要)

    數組在用方括號時做了一次加法才能取地址!
    所以在那些計算量超大的數據結構中,你每次都多做了一次加法!!!在 64 位系統下是 ??long long 相加,效率可想而知。

卡常數大法好!