2013-04-10 12 views
0

я в настоящее время извлечения данных из сокета следующим образомизвлечение данных из гнезда?

  boost::asio::read_until(*socket, buffer, "\n", error); 
      std::string s((std::istreambuf_iterator<char>(&buffer)), std::istreambuf_iterator<char>()); 

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

+1

первую очередь, пытаются выйти 'buffer' из цикла - он не должен быть воссоздан и перераспределена каждый раз –

+0

* медленно * является относительным понятием, какой производительности вы ожидаете? –

+0

Итак, вы профилировали код, а профилировщик указывает, что узкое место считывает данные из сокета? Независимо от того, может быть, стоит минимизировать объем выделения памяти и глубокие копии. –

ответ

2

Я работал над торговыми приложениями в прошлом и могу сказать, что я никогда не видел, чтобы какая-либо система маршрутизации заказов или система прямых кавычек когда-либо выполняли протокол, где он ищет «\ n». FIX, конечно, не поддерживает это. Это подразумевает, что где-то в вашей системе маршрутизации или котировки цены есть приложение, которое, скорее всего, принимает те сообщения ценовой категории, которые, вероятно, используют протокол FIX и преобразуют их в протокол, который вы сейчас используете. Скорее всего, это связано с тем, почему система работает медленно.

Если каждая строка представляет собой котировку акций, то я бы подумал о перезаписи системы, которая передает обновления цен, чтобы отправить их навалом, а не отправлять их более чем 3 - 5 раз в секунду - при условии, что система не используемые автоматизированными торговыми программами (что было бы совершенно другой темой и требовало бы совсем другого подхода). Похоже, это приложение также отправляет кавычки в формате ascii. Я бы изменил его на использование двоичного формата. FIX уже некоторое время поддерживает двоичный формат и называется FAST FIX. Также будет приемлемым бинарный протокол.

В зависимости от того, какую обработку вы делаете с котировкой акций, я бы не стал передавать каждую цитату в другую тему. Это особенно верно, если единственная обработка включает в себя просто обновление окна с новой цитатой. Я бы передал весь буфер (при условии, что он содержит более 1 цитаты и содержит только кавычки) для обработки потоком пользовательского интерфейса. Если необходимо выполнить другую обработку, например, сохранить ее на диск или базу данных, тогда у меня будет отдельный поток для обработки такого вида обработки.

Вы не указали нам много кода. Если клиентское приложение работает медленно, вы можете попробовать некоторые из следующих идей для улучшения:

  1. Не создавать потоки на лету. Создайте пул потоков в начале приложения и используйте их по мере необходимости. Поймите, что слишком много потоков могут быть хуже одного потока, поэтому попробуйте поэкспериментировать, чтобы найти счастливый баланс при принятии решения о количестве потоков.

  2. В том же духе, что и выше, попробуйте создать объекты только один раз и повторно использовать их, когда это необходимо. Это можно сделать, сохранив набор объектов в векторе, стеке или очереди. Только создайте новый объект, когда контейнер, удерживающий их, был исчерпан. Это особенно актуально, если ваше приложение часто создает объекты в куче с новым оператором.

  3. В вышеуказанном коде, как указал Панасюк, буфер можно перемещать за пределы цикла while. Объект ошибки также может. Ищите другие области вашего кода, где вы можете создать объект только один раз, а не создавать его снова и снова.

  4. Поймите, когда требуется экземпляр объекта .vs. статический. Экземпляр объекта обычно требуется, если ему нужно написать несколько потоков. Статический объект может использоваться, когда есть только один поток, или когда есть несколько потоков, которые нужно читать только с него.

  5. При передаче сообщений в поток пользовательского интерфейса из потока, обрабатывающего обработку сокетов, убедитесь, что вы используете BeginInvoke, а не Invoke. Invoke является синхронным и будет ждать завершения вызова вызываемого метода до его продолжения. BeginInvoke является асинхронным и сразу вернется, поэтому он более эффективен. Если приложение отключает сообщения, а Invoke используется, то почему.

  6. Поскольку приложение использует несколько потоков, разумно предположить, что есть некоторые объекты блокировки или операторы, используемые для предотвращения одновременного выполнения нескольких потоков. Посмотрите на эти случаи и убедитесь, что блокировки являются зернистыми по своему характеру - это означает, что блокировка не установлена ​​в верхней части функции для удобства .vs. устанавливая его где-то в середине функции, где это необходимо. Убедитесь, что код использует критические разделы вместо мьютексов, так как критические разделы в Microsoft на земле намного эффективнее. Единственный раз, когда нужно использовать мьютекс, при подключении DLL к двум или более exes, что редко делается больше.

Смежные вопросы