【问题标题】:Why isn't there a standard memswap function为什么没有标准的 memswap 功能
【发布时间】:2010-09-11 16:12:58
【问题描述】:

为什么 c 标准没有 memswap 函数,它可能看起来像:

int memswap(void *ptr1, void *ptr2, size_t nbytes)?

我知道它很容易编写,但我认为 libc 可以做一些很棒的技巧来加速它,就像某些实现为 memcpy 所做的那样。

【问题讨论】:

  • 这样的东西对于编写通用的就地排序函数很有用(类似于qsort)。

标签: c


【解决方案1】:

我认为是因为它并不经常需要。但是,在 C++ 中有一种简单的方法可以做到这一点:

#include <algorithm>

swap_ranges(ptr1, ptr1 + nbytes, ptr2)

它可能不如内置编译器优化,但它有可能比您自己编写的循环更快,因为它可能具有您不会实现的特定于平台的优化。

您确实需要小心上述内容,因为它假定 ptr1 和 ptr2 是 char 指针。更规范的方法是:

#include <algorithm>

swap_ranges(ptr1, ptr1 + num_items, ptr2)

【讨论】:

    【解决方案2】:

    这不是日常需要的。

    这些想法可能已经被考虑和放弃了,因为很难想出一个通用的算法。不要忘记 C 是一门古老的语言,扩展需要普遍有用。

    可能的错误情况:-

    • 交换范围重叠时的行为
    • 长度为零
    • 内存不足(最佳实现可能会为此分配内存)
    • 空指针

    最佳算法也可能取决于您在做什么,因此可以更好地由您直接编码。

    • 使用临时结构和赋值可能会更快地交换结构
    • 小长度 - 可能更好地分配临时内存
    • 长长度 - 逐节交换“节”(其中节是某个最佳长度)
    • 使用硬件复制功能

    【讨论】:

    • 最好的算法不一定是你的。 GCC 有 memset 作为关键字,根据你正在设置的内容,它可能会离开函数调用,或者有一个 for 循环,或者有一个展开的 for 循环等。这些天编译器很聪明。
    • 嗯,这些的自然结果是:重叠 -> UB,长度==0 -> 无操作,应该就地,可能使用固定数量的堆栈,空指针 - > UB。那里没有任何令人惊讶的地方。
    • 我同意最好的算法取决于你在做什么,但你也可以在没有动态缓冲区的情况下编写这个 memswap 函数,逐个字符复制 (sizeof(char)=1byte)
    • 所有这些可能的错误情况和优化机会同样适用于memcpy(除了内存不足,这对memcpy 不是问题,对@ 也不是问题987654325@ 任一)。我认为没有任何技术原因无法提供memswap
    • @Claudiu:GCC 不会将 memset 视为关键字。它将其视为函数的名称,但由于它是标准函数,因此允许替换它自己的实现。
    【解决方案3】:

    可能是因为它并不经常需要 - 我相当频繁地进行 memset 和 memcpy,但我不知道如果 memswap 可用的话我曾经使用过。

    【讨论】:

      【解决方案4】:

      在 C 编程中可能并不经常需要它,在 C++ 中,交换是对类成员进行的常规操作,而 std::swap 算法针对不同类型进行了高度优化。

      【讨论】:

      • std::swap 针对复杂类型(比如 std::vector)进行了优化,但(使用我知道的编译器)不是特别针对大型琐碎类型。
      猜你喜欢
      • 1970-01-01
      • 2014-02-25
      • 2021-05-07
      • 1970-01-01
      • 2015-04-13
      • 1970-01-01
      • 2022-01-14
      • 1970-01-01
      • 2011-11-15
      相关资源
      最近更新 更多