[英]Optimizing For Loops C++
我有一个小的功能,可以通过一个向量循环找到给定的动物并返回其栖息地。 我需要对其进行优化,但是我的工作陷入僵局。 突然出现在我size_t
三件事是size_t
, i++
和我正在遍历向量的事实。 我读到size_t
非常适合具有大尺寸索引的数组。 我知道pre-increment
比post-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.