zum Beispiel Nehmen wir an, dass ich zwei Funktionen haben, die fast genau die gleichen sind, die einen Engpass des Systems darstellen, das in etwa so aussehen, (viel komplizierter):Keeping-Code DRY ohne Einbußen beim Wirkungsgrad
void f1(int s)
{
for(size_t i = 0, END = m_v.size(); i < END; ++i)
{
int bin_id = binId(m_v[ i ], s);
m_result[ bin_id ] += m_w[ i ]; //
}
}
void f2(int s)
{
for(size_t i = 0, END = m_v.size(); i < END; ++i)
{
int bin_id = binId(m_v[ i ], s);
m_result[ bin_id ] += 1.f; //
}
}
Alles ist gleich, nur dass Sie entweder eine Variable oder eine Konstante in einer Zeile des Codes verwenden. Wie bereits erwähnt, ist der tatsächliche Code sehr viel komplexer. Es wäre schön, es nicht zweimal mit dem geringfügigen Unterschied zu duplizieren, da es einen erfordert, um sicherzustellen, dass jeder identisch bleibt. Ich könnte so etwas tun, sie in eine verschmelzen:
void f3(bool use_weight, int s)
{
if(use_weight)
{
for(size_t i = 0, END = v.size(); i < END; ++i)
{
int bin_id = binId(v[ i ], s);
result[ bin_id ] += m_w[ i ]; //
}
}
else
{
for(size_t i = 0, END = v.size(); i < END; ++i)
{
int bin_id = binId(v[ i ], s);
result[ bin_id ] += 1.f; //
}
}
}
Dies ist aber immer noch den Code zu duplizieren, nur innerhalb einer einzigen Funktion. Wir könnten dies tun, aber es wäre eine schlechtere Leistung geben:
void f3(bool use_weight, int s)
{
for(size_t i = 0, END = v.size(); i < END; ++i)
{
int bin_id = binId(v[ i ], s);
if(use_weight)
{
result[ bin_id ] += m_w[ i ]; //
}
else
{
result[ bin_id += 1.f; //
}
}
}
Und der Aufruf-Code sieht wie folgt aus:
bool use_weight = something.use_weight();
const int N = very_large_number;
for(int s = 0; s < N; ++s)
{
f3(use_weight, s);
}
Auch hier ist der Code unter der Annahme, viel komplizierter, so dass f3, zum Beispiel tatsächlich viel Logik duplizieren.
Ausschließen des Codes in eine 'Inline'-Funktion, die einen Parameter übernimmt und entweder eine Variable oder eine Konstante eingibt, sollte die Codeverdopplung vermeiden und den Compiler jedes Mal den entsprechenden Code ausgeben lassen. –
Wäre es ein Unterschied, dass Sie den 'bool' als Vorlagenparameter übergeben haben? – qxz
Sie könnten lambdas für den Code verwenden, der sich in den zwei Varianten unterscheidet, und eine Variable auf den entsprechenden Rückruf vor der Schleife festlegen. Der Funktionsaufruf-Overhead ist jedoch wahrscheinlich belastend, wenn dies eine Engpassfunktion ist. – Barmar