2016-03-13 31 views
-4

我有一個整數,數字代表輸出給用戶(類似於錯誤輸出)C++更快:if還是length?

如果整數小於100則表示錯誤,所以字體的樣式爲「The Error樣式」。

如果整數是更大然後100它是一個成功的消息,所以字體的樣式爲「成功樣式」,

我想延長這一點,例如添加一個新的樣式是超過1000的所有整數,等...

目前,我檢查一下這樣的:

if (m_errorNumber < 100) { 
    errorColor.setColor(255, 0, 0, 255); 
} else { 
    errorColor.setColor(0, 255, 0, 255); 
} 

現在我的理由是,如果我能使其更快,與例如檢查,如果整數的長度介於1和2或3或4等...

所以我詳細的問題是,我怎麼能找到正確的情況下儘可能快?

+0

沒有,真的沒有,但也許有一個更好的方法,我怎麼能做到這一點 – Gykonik

+2

如果是有區別的,它很可能小到不值得努力。你有沒有分析你的程序,看看實際的瓶頸在哪裏? –

+3

你真的低估了計算機能做這種微不足道的操作的速度。我想象一個'int'比較會轉化爲1或2個ASM指令。 –

回答

2

所以我詳細的問題是,我怎麼能儘快找到合適的案例?

你已經很少「如果不是...別的小」規則,所以性能是不是一個問題,沒有辦法,也沒有任何需要增加速度。一系列if可以很好地完成這項工作。除非你實際測量了速度並發現了瓶頸。然而,從計算機科學的角度來看,有可能提出一種解決方案,它可以提供更好的計算複雜度,使得必要的比較操作的數量將按比例減少,從而得到更大的n,即你有更多的規則。


讓我們來看看。您的「如果小於... else」規則構成了某些範圍,並且您的if的主體都使用不同的參數執行相同的操作。

這種情況可以被描繪成一個映射,其中每個範圍的末尾映射到一個參數集。在C++:

struct ColorArguments { int a; int b; int c; int d; }; 
std::map<int, ColorArguments> ranges; 

地圖將被如下填寫:

ranges[100] = { 255, 0 , 0 , 255 }; 
ranges[1000] = { 0, 255 , 0 , 255 }; 
ranges[std::numeric_limits<int>::max()] = { 0, 0, 0, 255 }; 

事實上,而不是加油吧,你倒是應該初始化它,讓它const

std::map<int, ColorArguments> const ranges = { 
    { 100,        { 255, 0 , 0, 255 } }, 
    { 1000,       { 0, 255 , 0, 255 } }, 
    { std::numeric_limits<int>::max(), { 0, 0, 0, 255 } } 
}; 

最後,upper_bound成員函數可以用來給你適當的ColorArguments對象。該函數返回一個迭代器到第一個元素,其鍵大於指定值。

例如,在此映射中,搜索500會給你一個指向帶有鍵1000的元素的指針,因爲1000是第一個大於500的鍵。

upper_bound對數的複雜性,這是相當不錯的,比你原來的if-else鏈的線性複雜度更好,儘管潛在的編譯器優化技術可以把這一線性代碼轉換成更復雜的東西。

auto const iter = ranges.upper_bound(m_errorNumber); 
auto const& colors = iter->second; 

說明了如何使用std::numeric_limits<int>::max()(你的機器上的最大可能int)作爲地圖的關鍵避免了特殊處理upper_bound返回ranges.end()(工作除非輸入本身可能是std::numeric_limits<int>::max(),在這種情況下,你確實需要一些特殊的處理)。

下面是一個完整的例子:

#include <map> 
#include <limits> 
#include <iostream> 

struct ColorArguments { int a; int b; int c; int d; }; 

void setColor(int a, int b, int c, int d) 
{ 
    std::cout << a << ", " << b << ", " << c << ", " << d << "\n"; 
} 

int main() 
{ 
    std::map<int, ColorArguments> const ranges = { 
     { 100,        { 255, 0 , 0, 1 } }, 
     { 1000,       { 0, 255 , 0, 2 } }, 
     { std::numeric_limits<int>::max(), { 0, 0, 0, 3 } } 
    }; 

    int const errorNumber = 500; 

    auto const iter = ranges.upper_bound(errorNumber); 

    setColor(
     iter->second.a, 
     iter->second.b, 
     iter->second.c, 
     iter->second.d 
    ); 
} 

算法的複雜性之外,該解決方案也變爲靜態的,硬編碼if-else邏輯進入數據,其可以被修改或在運行時動態地讀取。即使你不用它來解決你的具體問題,這也是一個需要記住的技巧。

+0

非常感謝,終於有一個人認真對待這個問題,並給出了很好的答案!非常感謝! :) – Gykonik