4

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

分析表明str*()方法需要很多时间。

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

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

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

你怎么看?

4

5 回答 5

3

利用std::string

于 2010-12-05T22:13:38.927 回答
3

分析表明 str*() 方法需要很多时间

当然可以……在任何阵列上操作都需要很多时间。

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

memcpy并不比strcpy. 事实上,如果您执行 astrlen来确定您要执行多少操作,memcpy那么strcpy几乎可以肯定会更快。

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

它可能看起来效率不高,但有很多比你或我更好的头脑在这方面工作

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

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

你怎么看?

我认为你的问题被问得很糟糕。没有提出真正的问题,这使得回答几乎是不可能的。我建议您将来真正提出具体问题。

于 2010-12-05T22:23:57.040 回答
2

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

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

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

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

于 2010-12-06T10:16:36.377 回答
1

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

替换strcpymemcpy没有任何显着差异;strcpy不做额外的传递来查找字符串的长度,它只是(概念上!)一个字符一个字符的副本,当它遇到终止 0 时停止。这并不比 贵很多memcpy,而且总是比strlen跟随便宜由memcpy.

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

于 2010-12-05T23:14:48.380 回答
0

我怎么看?我认为你应该做其他痴迷于预优化的人所做的事情。您应该找到最隐蔽、不可维护但直观(无论如何对您而言)的高性能方式,并以这种方式去做。听起来你已经pair<char*,len>有了 malloc/memcpy 的想法。

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

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

请记住,我在这里认为我是 100% 诚实的。我的身体里没有讽刺的骨头。

于 2010-12-05T22:48:09.080 回答