У меня есть алгоритм динамического программирования для рюкзака на C ++. Когда он был реализован как функция, и доступ к переменным был передан в него, потребовалось 22 секунды для запуска на конкретном экземпляре. Когда я сделал его функцией-членом моего класса KnapsackInstance и использовал переменные, являющиеся членами этого класса, запуску потребовалось 37 секунд. Насколько я знаю, только доступ к функциям-членам проходит через vtable, поэтому я не могу объяснить, что может происходить.
Вот код функции
int KnapsackInstance::dpSolve() {
int i; // Current item number
int d; // Current weight
int * tbl; // Array of size weightLeft
int toret;
tbl = new int[weightLeft+1];
if (!tbl) return -1;
memset(tbl, 0, (weightLeft+1)*sizeof(int));
for (i = 1; i <= numItems; ++i) {
for (d = weightLeft; d >= 0; --d) {
if (profitsWeights.at(i-1).second <= d) {
/* Either add this item or don't */
int v1 = profitsWeights.at(i-1).first + tbl[d-profitsWeights.at(i-1).second];
int v2 = tbl[d];
tbl[d] = (v1 < v2 ? v2 : v1);
}
}
}
toret = tbl[weightLeft];
delete[] tbl;
return toret;
}
tbl - это один столбец таблицы DP. Мы начинаем с первого столбца и продолжаем до последнего столбца. Переменная profitWeights - это вектор пар, первый элемент которого - прибыль, а второй - вес. toret - возвращаемое значение.
Вот код исходной функции: -
int dpSolve(vector<pair<int, int> > profitsWeights, int weightLeft, int numItems) {
int i; // Current item number
int d; // Current weight
int * tbl; // Array of size weightLeft
int toret;
tbl = new int[weightLeft+1];
if (!tbl) return -1;
memset(tbl, 0, (weightLeft+1)*sizeof(int));
for (i = 1; i <= numItems; ++i) {
for (d = weightLeft; d >= 0; --d) {
if (profitsWeights.at(i-1).second <= d) {
/* Either add this item or don't */
int v1 = profitsWeights.at(i-1).first + tbl[d-profitsWeights.at(i-1).second];
int v2 = tbl[d];
tbl[d] = (v1 < v2 ? v2 : v1);
}
}
}
toret = tbl[weightLeft];
delete[] tbl;
return toret;
}
Это было запущено в Debian Lenny с включенным g ++ - 4.3.2 и -O3 -DNDEBUG
Спасибо