我正在实现一个循环缓冲区来存储固定大小的数据结构,比如队列。该循环缓冲区初始化为三个参数: -
/*
* 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 call
和if statement
在速度方面有何关联?它们是等价的吗?
答案 0 :(得分:4)
不用担心速度,我可能只是编码:
if (buffer->callback) buffer->callback(item);
仅仅因为它是明确的和惯用的。它肯定不会比空函数调用慢。
答案 1 :(得分:3)
空存根函数实际上是两个JMP操作,并在CPU上分配PUSH / POP操作。 IF通常是单个COMP操作,比任何JMP + PUSHS + POPS便宜得多。
如果您的'IF通常返回false / true,那么我不会担心它,因为只要IF是“可预测的”(通常返回true或false),CPU通过预测结果以非常好的方式优化IF。有一些真/假的模式)
我会选择IF。