8

我正在实现一个循环缓冲区来存储固定大小的数据结构,如队列。这个循环缓冲区用三个参数初始化:-

/*
 * Initialize the ring buffer.
 * @capacity Max capacity of ring buffer.
 * @item_size Fixed size of item that will be put in this circular buffer.
 * @item_cleaner Clean callback, NULL if cleanup not required.
 */
ringbuf*
ringbuf_create(size_t capacity, size_t item_size, clean_up_cb item_cleaner)

我的循环缓冲区始终处于wrapping模式,这意味着当新项目放入完整的循环缓冲区时,最后一项总是被替换。由于动态分配的对象也可以放入这个缓冲区,因此循环缓冲区会保持引用一个清理回调函数,以便在替换或删除项目时释放它们。但同时这个回调函数也可以NULL(不需要清理的时候)。在我的代码的任何地方,我都有这样的陈述:-

if(buffer->callback != NULL)
   buffer->callback(item);

现在,为了防止这些if声明,当用户不提供任何回调函数时,我放置了空存根函数。这阻止我每次检查回调函数是否NULL存在。

使用这种方法,我的代码看起来很整洁。但我不确定,其中哪一个更快?在装配层面上,empty function callif statement速度方面有什么关系?它们是等价的吗?

4

2 回答 2

5

不用担心速度,我可能只是编写代码:

 if (buffer->callback) buffer->callback(item);

仅仅因为它是清晰和惯用的。它肯定不会比空函数调用慢。

于 2012-05-29T10:53:00.040 回答
4

一个空的存根函数实际上是两个 JMP 操作和 CPU 上分配的 PUSH/POP 操作。IF 通常是单个 COMP 操作,它比任何 JMP+PUSHS+POPS 都便宜得多。

如果您的 'IF' 通常返回 false/true,那么我不会担心它,因为 CPU 通过预测结果以非常好的方式优化 IF,只要 IF 是“可预测的”(通常返回 true 或 false 或具有某种模式)真/假)

我会选择IF。

于 2012-05-29T11:02:40.717 回答