1 使用std::codecvt进行Unicode转UTF8字符编码的时间效率测试

通常情况下,使用std::codecvt进行Unicode转UTF8编码会使用以下的函数:

std::string Std_UnicodeToUTF8(const std::wstring& unicodeStr)
{
    std::string ret;
    try
    {
        std::wstring_convert< std::codecvt_utf8<wchar_t> > unicode_to_utf8_conv;
        ret = unicode_to_utf8_conv.to_bytes(unicodeStr);
    }
    catch (const std::exception& e)
    {

    }
    return ret;
}

我所使用的测试时间效率的代码如下:

#include <iostream>
#include <string>
#include <codecvt>
#include <chrono>

std::string Std_UnicodeToUTF8(const std::wstring& unicodeStr)
{
    std::string ret;
    try
    {
        std::wstring_convert< std::codecvt_utf8<wchar_t> > unicode_to_utf8_conv;
        ret = unicode_to_utf8_conv.to_bytes(unicodeStr);
    }
    catch (const std::exception& e)
    {

    }
    return ret;
}


int main()
{
    auto beforeTime = std::chrono::steady_clock::now();

    std::wstring unicodeStr = L"我爱你中国我爱你中国我爱你中国我爱你中国我爱你中国我爱你中国我爱你中国我爱你中国我爱你中国我爱你中国我爱你中国我爱你中国";

    for (int i = 0; i < 5000; ++i)
    {
        std::string utf8 = Std_UnicodeToUTF8(unicodeStr);
    }


    auto afterTime = std::chrono::steady_clock::now();
    double duration_millsecond = std::chrono::duration<double, std::milli>(afterTime - beforeTime).count();
    std::cout << "Unicode转utf8耗时:" << duration_millsecond << "毫秒" << std::endl;
}

做5000次Unicode编码转UTF8编码字符串转换,上述代码在测试机上Debug耗时:944.763ms,Release耗时167.571ms。这个结果出来,我人都麻了,这个转换效率太慢了。

2 编码转换时间效率低的原因

经过观察代码我们发现,每调用一次Std_UnicodeToUTF8函数就要新建一个std::wstring_convert< std::codecvt_utf8 >对象,是不是这个对象创建过程十分耗时?不如换成static类型试一试。

3 换成static对象后的测试代码

#include <iostream>
#include <string>
#include <codecvt>
#include <chrono>

std::string Std_UnicodeToUTF8(const std::wstring& unicodeStr)
{
    std::string ret;
    try
    {
        static std::wstring_convert< std::codecvt_utf8<wchar_t> > unicode_to_utf8_conv;
        ret = unicode_to_utf8_conv.to_bytes(unicodeStr);
    }
    catch (const std::exception& e)
    {

    }
    return ret;
}


int main()
{
    auto beforeTime = std::chrono::steady_clock::now();

    std::wstring unicodeStr = L"我爱你中国我爱你中国我爱你中国我爱你中国我爱你中国我爱你中国我爱你中国我爱你中国我爱你中国我爱你中国我爱你中国我爱你中国";

    for (int i = 0; i < 5000; ++i)
    {
        std::string utf8 = Std_UnicodeToUTF8(unicodeStr);
    }


    auto afterTime = std::chrono::steady_clock::now();
    double duration_millsecond = std::chrono::duration<double, std::milli>(afterTime - beforeTime).count();
    std::cout << "Unicode转utf8耗时:" << duration_millsecond << "毫秒" << std::endl;
}

做5000次Unicode编码转UTF8编码字符串转换,上述代码在测试机上Debug耗时:104.362ms,Release耗时7.236ms。经过测试结果上看,修改为静态对象,在每次调用Std_UnicodeToUTF8函数时都是调用静态对象,而不是重新创建,这节省了巨大的时间开销。

对于高并发C++服务器,一般http请求为了节省带宽都是使用utf8编码,而C++业务服务器内部为国际化或者有处理中文字符串的需求,一般情况下会使用Unicode编码,所以在每一次请求时都需要进行UTF8->Unicode,Unicode->UTF8的转换,这就要求这个转换过程必须要快速。所以,请合理使用std::codecvt。