簡體   English   中英

優化循環C ++

[英]Optimizing For Loops C++

我有一個小的功能,可以通過一個向量循環找到給定的動物並返回其棲息地。 我需要對其進行優化,但是我的工作陷入僵局。 突然出現在我size_t三件事是size_ti++和我正在遍歷向量的事實。 我讀到size_t非常適合具有大尺寸索引的數組。 我知道pre-incrementpost-increment pre-increment更好,因為它會更改原始值,而不是創建臨時和增量。 但是編譯器通常無論如何都會優化這一小差異。 最后,我想到的最后一件事是該向量可能未排序,因此性能下降。 我當時正在考慮根據動物的物種變量對向量進行排序,然后可能將其移植到BST進行搜索,因為時間復雜度為O(log(n)) 這是我正在使用的代碼:

string GetAnimalHabitat(vector<Animal> animals, string species)
{
    for (size_t i = 0; i < animals.size(); i++)
    {
        if (animals[i].species == species)

        {
            return animals[i].habitat;
        }
    }
    return "Animal not within records.";
}

有什么我可能會缺少的東西可以改善此功能嗎? 任何提示都很好。 謝謝!

一個std::map肯定比在這里遍歷一個向量更好:

string GetAnimalHabitat(const map<string, string>& animals, const string& species)
{
    auto search = animals.find(species);
    if (search != animals.end())
        return search->second;
    return string("Animal not within records.");
}

但是,它需要先構建地圖。 但是,一次構建就足夠了,您只需向其添加新的密鑰對:

map<string, string> build_map(const vector<Animal>& animals)
{
    map<string, string> ret;
    for (const auto& x : animals)
        ret[x.species] = x.habitat;
    return ret;
}

您可以做的一件事是通過執行以下操作來減少調用.size()方法的次數:

size_t vectorSize = animals.size();
for (size_t i = 0; i < vectorSize; i++)
{
    if (animals[i].species == species)

    {
        return animals[i].habitat;
    }
}

另一個較小的問題是將i++更改為++i 這樣做的目的是避免每次i的值遞增時都將其存儲在寄存器中。

從高層次上講,您希望在每次調用此函數時停止對向量及其所有元素進行完整復制。 如果需要優化,我假設向量很大,那么為什么不將引用傳遞給const向量呢?

其次,另一個問題是向量中有多少個元素將與您的輸入字符串匹配? 如果只是少數幾個,則掃描整個向量會加載大量內存,只是為了查看它來決定您是否不需要它。 由於您是在第一場比賽后返回的,因此可以合理地認為每個物種中最多有一個,並且在這種情況下,關聯容器會更好。

一些對延遲敏感的地方會將數據划分為不同的組,因此不需要“過濾”。 只需查看您關心的一組事物,然后進行處理即可。

要考慮的另一件事是,字符串比較比整數比較慢得多。 您可以將種類預先哈希到類中,在循環之前對種類參數進行哈希,然后比較哈希值。 如果它們相等,則比較字符串以確保它是真正的匹配。

但是我的猜測是,您大部分時間都花在復制輸入和輸出上。

std::unordered_map最有意義,因為順序並不重要

string GetAnimalHabitat(const std::unordered_map<string, string>& animals, const string& species)
{
    auto search = animals.find(species);
    if (search != animals.end())
        return search->second;
    return string("Animal not within records.");
}

但是,它需要先構建地圖。 但是,一次構建就足夠了,您只需向其添加新的密鑰對。 請注意,第一次傳遞空的unordered_map,然后傳遞新值的向量和當前映射:

build_map(const std::vector<Animal>& animals, std::unordered_map<string_string> * ret)
{
    for (const auto& x : animals)
        ret[x.species] = x.habitat;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM