我想在一个不使用QT的项目中使用信号/槽库。我的要求很基本:
- 连接具有任意数量参数的两个函数。
- 信号可以连接到多个槽。
- 手动断开信号/槽连接。
- 良好的性能- 应用程序是基于帧的(即不是基于事件的),我想在每一帧中使用这些连接。
我已经阅读了libsigc++和Boost.Signals的比较。我也知道Boost.Signals的性能不佳。但我知道还有其他库,仍然不确定应该选择哪个库。
有没有信号/槽库的推荐?
我想在一个不使用QT的项目中使用信号/槽库。我的要求很基本:
我已经阅读了libsigc++和Boost.Signals的比较。我也知道Boost.Signals的性能不佳。但我知道还有其他库,仍然不确定应该选择哪个库。
有没有信号/槽库的推荐?
首先,尝试使用boost::signal。在你的特定情况下的应用程序中尝试之前,不要假设它速度不够快。
如果它不够高效,也许像FastDelegate这样的东西会适合你的需求?(我没有尝试过,但听说在一些boost::signal似乎不适合的情况下是一个很好的解决方案)。
无论如何,如果在你的应用程序中每帧都使用信号,将其替换为更简单的东西可能会更值得,比如容器,其中包含将在每帧调用的对象/函数。Signal更多的是为了允许立即管理“事件”,而不是使循环周期动态化(允许更改每帧调用的函数)。 (我有自己的解决方案(更新:现在非常古老和陈旧),我在游戏和其他一些地方大量使用,例如性能方面没有问题,因此类似的东西可能有所帮助)。
最近在对一些代码进行性能测试时,我惊讶地发现boost::signals函数排在了前面。对于那些不知道的人来说,boost::signals是一个非常有用的信号/槽库,可与boost::bind一起使用,用于类似于C#中所见的基于委托的事件处理。它稳健、功能丰富、灵活。但我发现,它也是非常、非常慢的。对于许多使用boost::signals的人来说,这没关系,因为他们很少调用事件。但是我每个对象每帧都要调用几个事件,结果是可预见的。
因此我编写了自己的事件库。虽然相对不那么灵活和功能丰富,但针对大多数人实际使用事件的方法进行了优化。事件调用速度比boost::signals快15到80倍。
查看链接。
最近接手了一个项目,发现connect
在我们的项目目标中产生了太多的开销。经过性能分析,发现信号中使用了互斥锁,在我们的信号使用中不需要这个锁。根据文档,成功地用虚拟互斥锁替换了它。这个互斥锁“速度非常慢”,所以请确保你需要它。这对于其他浏览此帖子的人可能有用。
原始代码:
typedef boost::signals2::signal_type<void()>::type signal_type;
新代码:
typedef boost::signals2::signal_type<void(), boost::signals2::keywords::mutex_type<boost::signals2::dummy_mutex> >::type signal_type;
COREEXTERN template class COREIMPEXP has_slots<SIGSLOT_DEFAULT_MT_POLICY>;
我以前使用过libsigc++,使用起来相当简单。我认为它不会有太多的性能损失,事实上,在一些地方,我喜欢使用槽而不是函数指针。
需要注意的一件事是,截至我上次使用(2年前),它被限制在通过连接传递的最多六个参数。
我没有使用boost库的经验,所以无法帮助您。
我曾使用过boost signals2库,但发现它非常慢。构造带有boost signals的对象时,99%的处理器时间被boost signals堆栈占用。即使只是使用一个简单的槽位进行信号发射,它的开销也非常大。我尝试了libsigc++,它明显更快。Libsigc++似乎非常快速和灵活。
创建了40000个对象,其中包含9个boost signals和9个libsigc++ signals:
我没有使用过libsig++,但我已经了解了它。我的信号和槽的先前经验来自Qt和一点来自Boost。如果您没有其中任何一个可用,则可以尝试使用我的信号和槽库(ksignals),该库存在于嵌入式代码(无动态内存分配)和“正常”的C ++代码(连接时进行动态内存分配)。
您可以在以下网址找到它:www.kjellkod.cc/signalandslots
在该页面上,您还可以找到比较:KSignals与Boost signals。
就速度而言,ksignals非常快,并且代码极其轻巧。它应该非常易于使用、理解和修改(如果需要)。
祝你好运 问候 Kjell H