我有渲染功能,但是用户可以通过设置函数指针来覆盖它;在每一帧中我都会检查它是否存在,如果没有,我会使用默认功能:
GK_EXPORT
void
gkScenePerLightRenderPath(GkScene *scene) {
/* ... */
do {
/* ... */
for (i = 0; i < c; i++) {
modelInst = objs[i];
if (!scene->renderModelFn)
gkRenderModel(scene, modelInst);
else
scene->renderModelFn(scene, modelInst);
}
} while (/* next light */);
}
我想也许我可以写下面的内容:
GK_EXPORT
void
gkScenePerLightRenderPath(GkScene *scene) {
/* ... */
GkRenderModelFn renderModelFn;
/* ... */
if (!scene->renderModelFn)
renderModelFn = gkRenderModel;
else
renderModelFn = scene->renderModelFn;
do {
/* ... */
for (i = 0; i < c; i++) {
modelInst = objs[i];
renderModelFn(scene, modelInst);
}
} while (/* next light */);
}
哪个更好?在第二个版本似乎我隐藏gkRenderModel
所以编译器可能无法应用优化?如果编译器将gkRenderModel
分配给指针并不重要,那么第二个似乎更优,因为if / else在两个循环之外?
答案 0 :(得分:2)
这取决于几个因素:
renderModelFn
(或其他任何线程)修改scene
对象gkRenderModel()
被声明为inline
。 如果它保证是外部/外部函数,并且循环中没有任何内容修改scene
指针中指向的对象,那么最好放置if
语句在循环之前,所以它只需要评估一次。
但是,如果被调用函数有可能修改传入的renderModelFn
对象的scene
成员,则在循环之前移动检查会改变行为。
此外,对函数指针的调用总是不符合要求。因此,在循环外移动if语句将会破坏任何内联的可能性。在这种情况下,最好将if
语句保留在循环中。