std::string性能优化示例

// g++-13  -O2  -std=c++17  main.cpp  profile.cpp
#include <iostream>
#include <chrono>
#include <mutex>       // std::mutex
#include <algorithm>   // std::remove_if

#include "profile.h"
#include "profile_rdtsc.h"

std::mutex mutex;

/* 初始版本——性能较差 */
PROFILE_REGISTER(remove_space);
std::string remove_space(std::string s)
{
    PROFILE_CHECK(remove_space);
    std::string result;
    for (size_t i = 0; i < s.length(); ++i) {
        if (!isspace(s[i])) {
            result = result + s[i];  // 会不断地构造新的std::string并析构之前的std:string
        }
    }
    return result;
}

/* 优化一,引用传参,使用std::string的operator+=运算符 */
PROFILE_REGISTER(remove_space_v1);
std::string remove_space_v1(const std::string& s)
{
    PROFILE_CHECK(remove_space_v1);
    std::string result;
    int length = s.length();
    for (size_t i = 0; i < length; ++i) {
        if (!isspace(s[i])) {
            result += s[i];
        }
    }
    return result;
}

/* 测试下std::string长度的计算放在for-loop中是否会增加耗时 */
PROFILE_REGISTER(remove_space_v2);
std::string remove_space_v2(const std::string& s)
{
    PROFILE_CHECK(remove_space_v2);
    std::string result;
    for (size_t i = 0; i < s.length(); ++i) {  // std::string长度的计算放在for-loop里会浪费时间
        if (!isspace(s[i])) {
            result += s[i];
        }
    }
    return result;
}

/* 测试下值传参是否会增加耗时 */
PROFILE_REGISTER(remove_space_v3);
std::string remove_space_v3(const std::string s)
{
    PROFILE_CHECK(remove_space_v3);
    std::string result;
    int length = s.length();
    for (size_t i = 0; i < length; ++i) {
        if (!isspace(s[i])) {
            result += s[i];
        }
    }
    return result;
}

/* 优化二,使用std::remove_if */
PROFILE_REGISTER(remove_space_v4);
std::string remove_space_v4(const std::string& s)
{
    PROFILE_CHECK(remove_space_v4);
    std::string result(s);
    auto pend = std::remove_if(result.begin(), result.end(), isspace);
    result = std::string(result.begin(), pend);

    return result;
}

/* 优化三,使用std::remove_if */
PROFILE_REGISTER(remove_space_v5);
std::string remove_space_v5(const std::string& s)
{
    PROFILE_CHECK(remove_space_v5);
    std::string result(s);
    result.erase(std::remove_if(result.begin(), result.end(), isspace), result.end());

    return result;
}

/* 优化四,使用reserve预分配内存+push_back */
PROFILE_REGISTER(remove_space_v6);
std::string remove_space_v6( std::string s)
{
    PROFILE_CHECK(remove_space_v6);
    std::string result;
    int length = s.length();
    result.reserve(length);
    for (int i = 0; i < length; ++i) {
        if (!isspace(s[i])){
            result.push_back(s[i]);
        }
    }

    return result;
}


int main() {
    std::cout << "===Begin of main!===\n";

    std::string input = "Hello World Hello World Hello World Hello World";
    constexpr int kLoops = 1000000;

    std::string result;
    for (int i = 0; i < kLoops; ++i) {
        // 这里加锁保护,在多线程中使用此工具需更加注意
        std::lock_guard guard{mutex};
        result = remove_space(input);
    }
    std::cout << result << std::endl;

    std::string result1;
    for (int i = 0; i < kLoops; ++i) {
        // 这里加锁保护,在多线程中使用此工具需更加注意
        std::lock_guard guard{mutex};
        result1 = remove_space_v1(input);
    }
    std::cout << result1 << std::endl;

    std::string result2;
    for (int i = 0; i < kLoops; ++i) {
        // 这里加锁保护,在多线程中使用此工具需更加注意
        std::lock_guard guard{mutex};
        result2 = remove_space_v2(input);
    }
    std::cout << result2 << std::endl;

    std::string result3;
    for (int i = 0; i < kLoops; ++i) {
        // 这里加锁保护,在多线程中使用此工具需更加注意
        std::lock_guard guard{mutex};
        result3 = remove_space_v3(input);
    }
    std::cout << result3 << std::endl;

    std::string result4;
    for (int i = 0; i < kLoops; ++i) {
        // 这里加锁保护,在多线程中使用此工具需更加注意
        std::lock_guard guard{mutex};
        result4 = remove_space_v4(input);
    }
    std::cout << result4 << std::endl;

    std::string result5;
    for (int i = 0; i < kLoops; ++i) {
        // 这里加锁保护,在多线程中使用此工具需更加注意
        std::lock_guard guard{mutex};
        result5 = remove_space_v5(input);
    }
    std::cout << result5 << std::endl;

    std::string result6;
    for (int i = 0; i < kLoops; ++i) {
        // 这里加锁保护,在多线程中使用此工具需更加注意
        std::lock_guard guard{mutex};
        result6 = remove_space_v6(input);
    }
    std::cout << result6 << std::endl;


    std::cout << "===End of main!===\n";
}
===Begin of main!===
HelloWorldHelloWorldHelloWorldHelloWorld
HelloWorldHelloWorldHelloWorldHelloWorld
HelloWorldHelloWorldHelloWorldHelloWorld
HelloWorldHelloWorldHelloWorldHelloWorld
HelloWorldHelloWorldHelloWorldHelloWorld
HelloWorldHelloWorldHelloWorldHelloWorld
HelloWorldHelloWorldHelloWorldHelloWorld
===End of main!===
---> Performance details begin: <---
Attention, overhead is 41 cycles, and it is removed from average duration.
[remove_space, called 1000000 times, total duration cycle is 1731695900, average duration cycle is 1690.7.]
[remove_space_v1, called 1000000 times, total duration cycle is 148790682, average duration cycle is 107.791.]
[remove_space_v2, called 1000000 times, total duration cycle is 156869002, average duration cycle is 115.869.]
[remove_space_v3, called 1000000 times, total duration cycle is 149592576, average duration cycle is 108.593.]
[remove_space_v4, called 1000000 times, total duration cycle is 166491025, average duration cycle is 125.491.]
[remove_space_v5, called 1000000 times, total duration cycle is 136679584, average duration cycle is 95.6796.]
[remove_space_v6, called 1000000 times, total duration cycle is 124020507, average duration cycle is 83.0205.]
---> Performance details end. <---

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值