我有渲染功能,但用户可以通过设置函数指针来覆盖它;在每一帧我都在检查它是否存在,如果没有,我正在使用默认功能:
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在两个循环之外?
这取决于几个因素:
renderModelFn
(或任何其他线程,就此问题)修改scene
对象gkRenderModel()
被宣布为inline
或不。如果它保证是外部/外部函数,并且循环中没有任何内容修改scene
指针中指向的对象,那么最好将if
语句放在循环之前,因此它只需要进行求值一旦。
但是,如果被调用的函数有可能修改传入的renderModelFn
对象的scene
成员,则在循环之前移动检查会改变行为。
此外,对函数指针的调用总是不符合要求。因此,在循环外移动if语句将会破坏任何内联的可能性。在这种情况下,最好将if
语句保留在循环中。