2011-03-19 3 views
1

У меня есть приложение, которое делает запросы к базе данных. Я думаю, это не имеет значения, какую базу данных я использую, но скажем, что это простая SQLite -driven база данных.C++ Benchmark tool

Теперь это приложение работает как служба и выполняет некоторое количество запросов в минуту (это число может быть огромным).

Я хочу сравнить запросы, чтобы получить их число, максимальное/минимальное/среднее время работы в течение некоторого периода, и я хочу создать свой собственный инструмент для этого (очевидно, есть некоторые, но мне нужно мое собственное по некоторым подходящим причинам :).

Так что - можете ли вы посоветовать подход к этой задаче?


Я предполагаю, что есть несколько возможных случаев:

1) У меня есть доступ к исходному коду приложения.Здесь, очевидно, я хочу сделать какую-то кросс-интеграцию приложений, возможно, используя каналы. Не могли бы вы посоветовать что-то о том, как это сделать и (если есть) любое другое возможное решение?

2) У меня нет источников. Итак, можно ли даже выполнить какую-то опрятную инъекцию из моего приложения, чтобы сравнить другую? Надеюсь, есть способ, может быть, взломать, что угодно.

Большое спасибо.

+0

для Windows или Unix? –

+0

@John Unix в порядке, многоплатформенное решение было бы лучшим. –

+0

Звучит как «инструмент сравнения SQL» для меня. Не C++. Вы заинтересованы в производительности ваших SQL-запросов. – jalf

ответ

2

Мой ответ действителен только для случая 1).

В моем опыте профилирования это трудная задача. Использование профессиональных инструментов может быть эффективным, но может потребоваться много времени, чтобы найти правильный и научиться правильно его использовать. Обычно я начинаю очень просто. Я подготовил два очень простых занятия. Первый класс ProfileHelper заполняет время начала в конструкторе и время окончания деструктора. Второй класс ProfileHelperStatistic - это контейнер с дополнительной статистической способностью (std :: multimap + несколько методов для возврата среднего, стандартного отклонения и других забавных вещей).

ProfilerHelper имеет ссылку на контейнер и перед выходом деструктор нажимает данные в контейнере.Вы можете объявить ProfileHelperStatistic в основном, и если вы создадите в стек ProfilerHelper в начале определенной функции, задание будет выполнено. Конструктор ProfileHelper будет хранить время начала, а деструктор будет вызывать результат на ProfileHelperStatistic.

Его довольно легко реализовать и с незначительной модификацией можно реализовать как кросс-платформенную. Время создания и уничтожения объекта не записывается, поэтому вы не будете загрязнять результат. Вычисление итоговой статистики может быть дорогостоящим, поэтому я предлагаю вам запустить его один раз в конце.

Вы также можете настроить информацию, которую собираетесь хранить в ProfileHelperStatistic, добавляя дополнительную информацию (например, временную метку или использование памяти).

Реализация довольно проста, два класса, которые не более 50 строк каждый. Всего двух советов:

1) поймать всех в деструкторе!

2) считают, что использовать коллекцию, которая занимает постоянное время для вставки, если вы собираетесь хранить много данных.

Это простой инструмент, который может помочь вам профилировать ваше приложение очень эффективным способом. Мое предложение состоит в том, чтобы начать с нескольких макрофункций (5-7 логических блоков), а затем увеличить степень детализации. Помните правило 80-20: 20% исходного кода используют 80% времени.

Последнее примечание о базе данных: база данных настраивает производительность динамически, если вы запускаете запрос несколько раз в конце, запрос будет быстрее, чем в начале (Oracle делает, я думаю, и другая база данных). Другими словами, если вы тщательно и искусственно тестируете приложение, сосредоточенное на нескольких конкретных запросах, вы можете получить слишком оптимистичные результаты.

+0

Хотя это не работает как полный ответ, это дало мне несколько идей для размышлений. Спасибо. –

+0

добро пожаловать. –

1

Я предполагаю, что это на самом деле не имеет значения, какие базы данных я использую, , но давайте говорить, что это просто SQLite управляемой базы данных.

Очень важно, какую базу данных вы используете, потому что менеджер баз данных может иметь интегрированный мониторинг.

Я мог говорить только о IBM DB/2, но я полагаю, что IBM DB/2 - это не единственный dbm со встроенными средствами мониторинга.

Вот например, краткий обзор того, что вы могли бы контролировать в IBM DB/2:

  • заявления (все выполненные заявления, граф выполнения, подготовьте времени, CPU-время, кол-во операций чтения/записи: tablerows , Буферный, логические, физические)
  • таблицы (количество операций чтения/записи)
  • буферные (логических и физических операций чтения/записи данных и индекса, время чтения/записи)
  • активные соединения (выполняющихся операторов, подсчет чтение/запись, раз)
  • замки (все замки и типа)
  • и многие другие

Монитор-данные могут быть доступны через SQL или API из собственного программного обеспечения, как, например, DB2 Monitor делает.

-1

Вам необходимо ориентированное на аспект решение.

Отъезд AspectC++.

+0

Что касается аспектно-ориентированного программирования, связанного с этим вопросом? –

+0

"сравнивает запросы, чтобы получить их число, максимальное/минимальное/среднее время работы в течение некоторого периода". Способ сделать это (и какие инструменты, такие как CA Wily Introscope), служит инструментом для кода в интерфейсе, который указывает на внешнюю систему, о которой идет речь. OP специально отмечает, что он хочет сделать это на стороне приложения, а не в базе данных. Все, что необходимо, - это впрыскивание аспектов каротажа. Это даже возможно для инструмента dll, чей код у вас нет доступа (некоторые вирусы работают таким образом), хотя я не знаю, выполнимо ли это с aspectC++ (я так полагаю). – mcyalcin

+0

http://www.lsi.upc.edu/~jlberral/documents/alonso-dpdns10.pdf - пример аналогичного усилия. – mcyalcin

0

Здесь, очевидно, я хочу сделать какую-то кросс-интеграцию приложений, возможно, используя трубы.

Я не думаю, что это очевидно.

Если у вас есть доступ к приложению, я бы предложил сбросить всю необходимую информацию в файл журнала и обработать этот файл журнала позже. Если вы хотите активировать и деактивировать это поведение «на лету», без повторного запуска службы, вы можете использовать библиотеку протоколирования, которая поддерживает включение/выключение протоколов журнала «на лету». Тогда вам нужно будет отправить сообщение в службу любыми способами (подключение сокетов, ...), чтобы включить/отключить ведение журнала.

Если у вас нет доступа к приложению, я думаю, что лучший способ - это то, что предложил МакГэки: пусть это делают инструменты профилирования/мониторинга СУБД. Например. MS-SQL имеет хороший профилировщик, который может захватывать запросы на сервер, включая все виды полезных данных (время процессора для каждого запроса, время ввода-вывода, время ожидания и т. Д.).

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

1

В Unix вы можете использовать gprof и его графический интерфейс, kprof. Скомпилируйте приложение с флагом -pg (предположим, вы используете g ++) и запускаете его через gprof и наблюдаете результаты.

Обратите внимание, что этот тип профилирования будет измерять общую производительность приложения, а не только SQL-запросы. Если это производительность запросов, которые вы хотите измерить, вы должны использовать специальные инструменты, предназначенные для вашей СУБД, например MySQL имеет встроенный запрос-профилировщик (для SQLite см. Этот вопрос: Is there a tool to profile sqlite queries?)

0

Использование apache jmeter , Для проверки исполнения ваших SQL-запросов при высокой нагрузке

1

Существует а (Linux) решение, которое вы могли бы найти интересным, так как он может быть использован в обоих случаях.

Это LD_PRELOAD трюк. Это переменная среды, которая позволяет вам указать общую библиотеку для загрузки непосредственно перед вашей программой. Загрузка символов из этой библиотеки будет переопределять любые другие доступные в системе.

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

Существует куча ресурсов, которые объясняют, как использовать этот трюк: 1, 2, 3