IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    Actor里的偏函数与性能

    hongjiang发表于 2015-09-22 13:27:34
    love 0

    Evan Chan分享的《Akka in Production: Our Story》是一篇非常务实的工程实践分享,里面有很多可借鉴的点子,其中的一个对消息接受的包装逻辑主要预留了扩展点:

    trait ActorStack extends Actor {
    
        def wrappedReceive: Receive // Receive类型是一个偏函数
    
        def receive: Receive = {
            case x => if (wrappedReceive.isDefinedAt(x)) wrappedReceive(x) else unhandled(x)
        }
    }
    

    大部分人在实现业务逻辑时可能如下

    class MyActor extends ActorStack {
    
        def wrappedReceive: Receive = {
            case Something => balabala
        }
    }
    

    这种情况下会有个小小的性能浪费,每次接收消息的时候,至少要创建一次偏函数对象。如果消息又正好在wrappedReceive里定义了的话,创建了2次偏函数对象,因为调用了2次wrappedReceive方法;这个是可以避免的,用一个成员把这个偏函数对象保存起来,避免每次都创建:

    trait ActorStack extends Actor {
    
        def wrappedReceive: Receive
    
        private val logic = wrappedReceive
    
        def receive: Receive = {
            case x => if (logic.isDefinedAt(x)) logic(x) else unhandled(x)
        }
    }
    

    或许看客们又好奇,那么Akka对receive这个函数返回的偏函数又是怎么处理的?是否也存在每次都生产一下(同样的性能浪费),还是保存在某个地方? 没错,它在底层实现里是被放到behaviorStack这个行为栈里的,每次处理逻辑的时候从行为栈里取出这个偏函数进行调用。



沪ICP备19023445号-2号
友情链接