如何提高该函数的运行效率?

How can the runtime efficiency of this function be improved?

本文关键字:运行 效率 函数 何提高      更新时间:2023-10-16

我正在尝试编写最佳代码(良好的运行时效率(来删除句子中的重复单词。

例如,Jack Juliet Juliet Jill Jack Romeo Jack Jill函数的输入字符串应返回Jack Juliet Jill Romeo

以下是我的代码:

std::string removeDuplicateWords(const std::string& str)
{
std::stringstream ss (str);
std::unordered_set<std::string> string_history;
std::string current_string, output_string;
ss >> current_string;
string_history.insert(current_string);
output_string += current_string;
while(ss >> current_string) {
if(string_history.find(current_string) == string_history.end()) {
output_string += " " + current_string;
string_history.insert(current_string);
}
}
return output_string;
}

对于此示例,获得性能没有多大意义,如果您只有大约 10 个单词要处理,请使用更简单的代码。但是,您可以执行一些操作来提高性能。

首先,您不想检查某个元素是否在集合中。insert返回一对迭代器布尔值,其中第一个是带有键(现有或新(的元素的迭代器,第二个是指示是否发生了插入的布尔值。

if (string_history.insert(current_string).second)
output_string += " " + current_string;

这既简化了代码,又提高了性能。如注释中所述,使用std::move是有意义的,但是,如果您将其与 insert 一起使用,则需要迭代器来获取移动到的对象。 对于这种情况,它无济于事,就像您在 SSO 案例中一样。

需要更多代码的第二件事是 删除std::stringstream.流会产生一些开销。相反,您可以更好地接受std::string_view并使用子字符串逻辑将其切成碎片。这可以防止创建新的字符串对象,并消除流的开销。您确实需要 C++17(或提供此内容的库(。

最后,您可以在开始时保留output_string,您知道最大大小(也称为str的大小(。如果最终超出 SSO 范围,这可以防止重新分配。

改进:

  • 您无需检查字符串是否存在,因为unordered_set会为您执行此操作。
  • current_string被感动了,因为我们不再需要它。

    std::string removeDuplicateWordsImproved( const std::string& str )
    {
    std::stringstream ss (str);
    std::unordered_set<std::string> string_history;
    std::string current_string, output_string;
    while( ss >> current_string )
    string_history.insert( std::move( current_string ) );
    for ( auto& word : string_history )
    output_string.append( std::move( word ) ).push_back( ' ' );
    output_string.erase( output_string.size() - 1 );
    return output_string;
    }