NULL终止字符串及其长度

时间:2010-12-05 22:10:15

标签: c++ gcc cstring

我有一个遗留代码,它接收一些专有的,解析它并创建一堆静态字符数组(嵌入在表示消息的类中),以表示NULL字符串。之后,指向字符串的指针四处传递,最后序列化为某个缓冲区。

分析表明str*()方法需要花费大量时间。

因此我想使用memcpy()是否可能。为了实现它,我需要一种方法将长度与指向NULL终止字符串的指针相关联。我虽然关于:

  • 使用std::string看起来效率较低,因为它需要内存分配和线程同步。

  • 我可以使用std::pair<pointer to string, length>。但在这种情况下,我需要“手动”保持长度。

您怎么看?

5 个答案:

答案 0 :(得分:3)

使用std::string

答案 1 :(得分:3)

  

分析显示str *()方法   花很多时间

当然可以......在任何阵列上进行操作需要花费很多时间。

  

因此我想使用memcpy()   是否有可能。要实现它我   需要一种方法来将长度与   指向NULL终止字符串的指针。一世   虽然关于:

memcpy实际上并不比strcpy慢。事实上,如果您执行strlen来确定您要去多少memcpy,那么strcpy几乎肯定会更快。

  

使用std :: string看起来更少   高效,因为它需要记忆   分配和线程同步

看起来效率可能会低一些,但是有很多比你的更好的思想,或者我的有更好的思想

  

我可以使用std :: pair。但在这种情况下我需要   保持长度“手动”。

这是节省时间计算长度的一种方法。显然你需要手动保持长度。这就是windows BSTR的有效工作方式(尽管长度存储在内存之前,实际的字符串数据中)。 std::string。例如,已经这样做了......

  

您怎么看?

我认为你的问题非常严重。没有真正的问题,这使得回答几乎不可能。我建议你在将来提出具体问题。

答案 2 :(得分:2)

使用std::string。这是一个已经给出的建议,但让我解释一下原因:

一,它使用自定义内存分配方案。你的char*字符串可能是malloc'ed。这意味着它们是最坏情况对齐的,char[]实际上并不需要。 std::string不会遭受不必要的调整。此外,std::string的常见实现使用“小字符串优化”,它完全消除了堆分配,并改善了引用的局部性。字符串大小将与char[]本身位于同一缓存行中。

二,它保持字符串长度,这确实是速度优化。大多数str*函数都较慢,因为它们没有预先提供此信息。

第二个选项是rope类,例如来自SGI。通过消除一些字符串副本,这会更有效。

答案 3 :(得分:1)

您的帖子没有解释str*()函数调用的来源;绕过char *肯定不会调用它们。确定实际执行字符串操作的站点,然后尝试找出它们是否效率低下。一个常见的缺陷是strcat首先需要扫描终止0字符的目标字符串。如果连续多次调用strcat,最终可能会得到O(N ^ 2)算法,所以要小心。

strcpy替换memcpy没有任何重大差异; strcpy没有额外的传递来查找字符串的长度,它只是(概念上!)一个逐个字符的副本,当它遇到终止0时停止。这并不比{更贵} {1}},并且始终比memcpy便宜strlen

获得字符串操作性能的方法是尽可能避免复制;不要担心复制速度更快,而是尝试复制更少!这适用于所有字符串(和数组)实现,无论是memcpychar *std::string还是某些自定义字符串/数组类。

答案 4 :(得分:0)

我怎么想?我认为你应该做其他人对预优化所痴迷的事情。您应该找到最模糊,不可维护但直观(对您而言)高性能的方式,并且可以这样做。听起来好像你正在使用带有malloc / memcpy想法的pair<char*,len>

无论您做什么,都不要使用预先存在的优化轮子,以便于维护。当您沉迷于直观测量的性能提升时,可维护性是最难以想象的事情。此外,正如您所知,您比编写编译器及其标准库实现的人更聪明。这么多,以至于你要相信他们对任何事情的判断是非常愚蠢的;你应该考虑自己重写整个事情,因为它会表现得更好。

而且......你要做的最后一件事就是用一个分析器来测试你的直觉。那太科学和有条理了,我们都知道科学是一堆从来没有给我们任何东西的铺位;我们也知道,个人的直觉和启示永远不会错。当你已经直观地掌握了情况的看似时,为什么要用客观的工具浪费时间呢?

请记住,我在这里看到的是100%诚实。我体内没有讽刺骨头。