oop — C / C ++: есть ли снижение производительности за использование шаблона адаптера?

я использую высокопроизводительная / параллельная библиотека графов написанный на C в проекте C ++. Это обеспечивает структуру stinger (структура данных графа) и такие операции, как

int stinger_insert_edge_pair (struct stinger *G,
int64_t type, int64_t from, int64_t to,
double weight, int64_t timestamp) { .... }

Однако в большинстве случаев я не хочу указывать временные метки, а также веса или типы. Параметры по умолчанию было бы хорошо. Кроме того, ООП-подобный интерфейс был бы хорош: G->insertEdge(u, v) вместо insert_edge_pair(G, u, v, ...),

Так что я думал о создании адаптер класс выглядит

class Graph {

protected:

stinger* stingerG;

public:

/** default parameters ***/

double defaultEdgeWeight = 1.0;/** methods **/

Graph(stinger* stingerG);

virtual void insertEdge(node u, node v, double weight=defaultEdgeWeight);

};

Метод insertEdge(...) просто звонит stinger_insert_edge_pair(this->stingerG, ...) с соответствующими параметрами.

Тем не менее, производительность является ключевым аспектом здесь. Какое снижение производительности связано с использованием такого класса адаптера? Стоит ли ожидать снижения производительности по сравнению с использованием «голой» библиотеки?

1

Решение

Если ваш insertEgde просто перенаправляет вызов stinger_insert_edge_pair, то (скорее всего) не будет никакой разницы в коде, сгенерированном между простым вызовом stinger_insert_edge_pair и g-> insertEdge (при условии, что вы удалите виртуальный спецификатор).
Сравнение кода сборки, сгенерированного с помощью простого вызова и вызова адаптера, позволило бы получить достоверную информацию о накладных расходах, которые несет ваш адаптер.

Должен ли insertEdge быть виртуальным? Планируете ли вы иметь подклассы Graph? Но опять же, стоимость вызова виртуальной функции практически ничтожна по сравнению с реальной стоимостью самого выполнения функции.

1

Другие решения

Если вы используете тривиальный inline методы, компилятор должен встроить их в точку вызова, чтобы не было никакого снижения производительности. Однако обратите внимание, что вы не должны использовать виртуальные функции для этого.

1

Виртуальная функция обычно не может быть встроенным, поэтому при вызове функции возникают такие же издержки (передача параметров в стек, возможное нарушение работы конвейера и кэша и т. д.). На практике вызов обычной функции очень быстрый — порядка тактов. Единственный способ узнать наверняка, уместно ли это тестовое задание по вашему собственному заявлению.

1