有没有办法让这个tolower(..)代码更快

Is there a way to make this tolower( ... ) code faster?

本文关键字:代码 tolower 有没有      更新时间:2023-10-16

在浏览了web之后,我想出了以下代码来将char16_t*字符串转换为小写。

速度在我的应用程序中相当重要,所以我想知道是否有办法让这个功能更快?

std::u16string ToLower(const char16_t* str)
{
  std::u16string data(str ? str : u"");
  std::u16string ldata;
  for (std::u16string::const_iterator it = data.begin(); it != data.end(); ++it)
  {
    ldata.push_back( std::use_facet<std::ctype<char16_t>>(std::locale()).tolower(*it) );
  }
  return ldata;
}

我有一部分认为"push_back(…)"部分本身并不是最有效的。

也许我甚至根本不能使用std::u16string,而是返回char16_t*并让调用函数删除该指针。

// pseudo code - untested
// edited with suggestion from @Dietmar Kühl
char16_t* ToLower(const char16_t* str)
{
  if( NULL == str )
  {
    return NULL;
  }
  int l = strlen16( str );
  char16_t* ldata = new char16_t[ l + 1];
  auto const& ct = std::use_facet<std::ctype<char16_t>>(std::locale());
  for (int i = 0; i < l; ++i )
  {
    ldata[i] = ct.tolower(str[i]);
  }
  ldata[l] = u''; 
  return ldata;
}

但是,"std::use_facet(…)"还能更快吗?

编辑1

我进行了一些测试,给出了下面的评论

  • 1000个字符的字符串
  • 进行了1000次测试
  • 时间一般

结果为

  • 11ms-我的原始代码,(std::use_facet in the loop)
  • 10ms-std::use_facet在循环外
  • 10ms-std::use_facet在循环外并使用ldata.rereserve(…)
  • 4ms-仅使用char16_t*,(调用者必须删除)
  • 5ms-仅使用char16_t*,但返回std::u16string(函数管理删除)
  • 4ms-同时包含多个字符

因此,char16_t*ToLower(const char16_t*str){…}函数看起来像是一个胜利。还有其他建议吗?

对于初学者来说,您应该获得循环之外的方面。这可能会产生巨大的差异,尤其是对于语言环境库的实现不太好的情况:

auto const& ct = std::use_facet<std::ctype<char16_t>>(std::locale());
for (std::u16string::const_iterator it = data.begin(); it != data.end(); ++it)
{
    ldata.push_back( ct.tolower(*it) );
}

还有一个成员tolower()的重载,它转换一个对象数组并只调用底层virtual函数一次。也就是说,你可能想把它用作

std::u16string ToLower(const char16_t* str)
{
    if (!str) {
        return std::u16string();
    }
    std::u16string data(str);
    std::use_facet<std::ctype<char16_t>>(std::locale()).tolower(&data[0], &data[0] + data.size());
    return data;
}