【问题标题】:strcpy vs memcpy for copying char * with known sizestrcpy vs memcpy 用于复制已知大小的 char *
【发布时间】:2014-09-19 08:11:40
【问题描述】:

我不关心 NULL 终止符,所以我有两个选择:

strcpy(createTabStmt, "CREATE TABLE "); //shorter and more readable code

或者

memcpy(createTabStmt, "CREATE TABLE ", sizeof ("CREATE TABLE ") - 1); //faster?

memcpy 版本总是更快吗?

--

如果是这样,那么我认为宏可以使可读性与strcpy一样好:

#define MEMCPY_LITERAL(ptr,literal) memcpy(ptr, literal, sizeof (literal) - 1)

--

我认为memcpy 版本还有一个常量sizeof ("CREATE TABLE ") - 1。所以它使用更多的空间。这是真的吗?

【问题讨论】:

  • 这是你程序的瓶颈吗?如果没有,您担心的是性能差异可以忽略不计,而没有真正的收益。过早的优化是一件坏事。过早的微优化是可怕的。
  • sizeof ("CREATE TABLE ") 的评估结果是什么?
  • 它们不相等。 strcpy 形式多写一个字节。我不确定你是否关心,但如果不关心,你为什么要麻烦在第二个版本中减去一个?
  • @DavidHeffernan:对象的大小:14。

标签: c memcpy literals strcpy


【解决方案1】:

Strcpy 将进行大量优化,我的期望是您将无法衡量这两个语句之间的差异。那,数据库将在CREATE TABLE 上做成千上万的事情,所以你应该在这里优化可读性。只需使用 strcpy,人们知道它是什么,编译器知道它是什么,它可以完美地满足您的需求。

【讨论】:

    【解决方案2】:

    如果知道大小,通常memcpy 的非简单实现比 strcpy 快,因为它利用了 CPU 的数据总线大小。例如,如果您要复制 16 字节,在 64 位 CPU 中的良好实现会将数据传输分解为两个 8 字节副本。这是通过将源指针和目标指针转换为 64 位变量指针,然后通过两次迭代读取/写入内存来实现的。

    检查此链接: Understanding the source code of memcpy()

    【讨论】:

      【解决方案3】:

      假设源代码是​​一个字面量,我希望任何体面的优化编译器都能为其中任何一个做同样的事情(以你的memcpy 版本少写一个字节的事实为模):要么以适当的大小调用memcpy ,或生成内联代码将内容直接存储到目的地。您可以使用 gcc 和兼容的编译器验证这一点,方法是使用 -S 而不是 -c 输出汇编语言,或反汇编输出程序。

      【讨论】:

        【解决方案4】:

        作为基本规则,您应该将 strcpy 用于字符串,将 memcpy 用于数据。 一旦您开始更改它以节省微不足道的性能,您就会使代码变得不可读和混乱。

        这也适用于宏 - 您也应该避免使用它们,因为它们可能会导致任何重写您的代码的人(或从现在开始几个月/几年)的编译错误

        这在大多数情况下都是如此,除非您编写的代码对性能至关重要(大多数情况下并非如此)

        【讨论】:

        • 不同意“作为基本规则,您应该将 strcpy 用于字符串,将 memcpy 用于数据。”。字符串操作通常是整体性能问题的根源,因此“将其更改为可忽略不计的性能节省”是一个错误的前提。 OP 的示例可能过于简单化,以支持您关于可忽略的性能节省的想法,但标题问题仍然是一个真正有效的问题,此处未回答。
        猜你喜欢
        • 2021-06-23
        • 2015-09-17
        • 1970-01-01
        • 2021-08-11
        • 2011-02-23
        • 1970-01-01
        • 1970-01-01
        • 2020-04-22
        • 2016-09-11
        相关资源
        最近更新 更多