我目前正以下列方式从套接字中提取数据
boost::asio::read_until( *socket, buffer, "\n", error );
std::string s( (std::istreambuf_iterator<char>(&buffer)), std::istreambuf_iterator<char>());
似乎拉动机制很慢,我需要更快地提取更多数据。关于我可以做些什么来提高性能的任何建议?在某种程度上我可以创建另一个套接字并将一些提取工作委托给那个吗?
答案 0 :(得分:2)
我过去曾经在交易应用程序,可以告诉你,我从未见过任何订单路由系统或实时报价系统曾经实现过搜索“\ n”的协议。 FIX肯定不支持这个。这意味着在您的订单路由或实时报价系统中的某个地方,有一个应用程序最有可能采用那些可能使用FIX协议并将它们转换为您现在使用的协议的价格报价消息。这很可能至少与系统运行缓慢有关。
如果每个字符串代表股票报价,那么我会考虑重新编写广播价格更新的系统以批量发送它们而不是每秒发送超过3到5次 - 假设系统不是自动交易程序使用(这将是一个完全不同的主题,需要一个非常不同的方法)。看起来该应用程序也以ascii文本格式发送引号。我会改变它以使用二进制格式。 FIX已经支持二进制格式很长一段时间了,被称为FAST FIX。自定义二进制协议也是可以接受的。
根据您使用股票报价进行的处理类型,我会考虑不将每个报价传递给不同的线程。如果唯一的处理只涉及使用新引号更新窗口,则尤其如此。我将传递整个缓冲区(假设它有多个引号并且只包含引号),以供用户界面线程处理。如果需要进行其他处理,例如将其保存到磁盘或数据库,那么我将有一个单独的线程来处理这种处理。
您没有向我们展示太多代码。如果客户端应用程序运行缓慢,那么您可以尝试以下一些改进建议:
不要动态创建线程。在应用程序的开头创建一个线程池,并根据需要使用它们。了解太多线程可能比一个线程更糟糕,所以在决定线程数时尝试尝试找到一个快乐的平衡。
与上述相同,尝试只创建一次对象,并在需要时重复使用它们。这可以通过在向量,堆栈或队列中存储一组对象来完成。仅在创建新对象时 拿着它们的容器已经用尽了。如果您的应用经常使用new运算符在堆上创建对象,则尤其如此。
在上面的代码中,正如Panasyuk指出的那样,缓冲区可以移动到while循环之外。错误对象也可以。在代码中查找可以只创建一次对象而不是一遍又一遍地创建对象的其他区域。
了解何时需要对象的实例.vs。一个静态的。如果多个线程需要写入对象,则通常需要对象的实例。当只有一个线程时,或者当有多个线程只需要从中读取时,可以使用静态对象。
从处理套接字处理的线程向用户界面线程传递消息时,请确保使用BeginInvoke而不是Invoke。 Invoke是同步的,将等待被调用的方法在继续处理之前完成。 BeginInvoke是异步的,会立即返回,因此效率更高。如果应用程序正在删除消息并且正在使用Invoke,那么这就是原因。
由于应用程序使用多个线程,因此可以合理地假设有一些锁定对象或语句用于防止同时执行多个线程。查看这些情况并确保锁本质上是粒状的 - 这意味着为方便起见,锁没有设置在函数的顶部.vs。将它设置在只需要它的函数中间的某个位置。确保代码使用关键部分而不是互斥体,因为Microsoft域中的关键部分更有效。唯一需要使用互斥锁的是将DLL附加到两个或更多exes时,很少再这样做了。