为什么即使线程池中有更多线程,scala期货也不能更快地运行?

时间:2015-06-25 10:59:50

标签: scala threadpool future

我对scala有以下算法:

  1. 初始调用db以初始化游标
  2. 从db(返回Future)获取1000个实体
  3. 对于每个实体处理一个额外的数据库请求和获取修改的实体(返回未来)
  4. 转换原始实体
  5. 将转化后的实体置于#3
  6. 的Future回调中
  7. 等待所有期货
  8. 在scala中它有点像:

     val client = ...
     val size = 1000
     val init:Future = client.firstSearch(size) //request over network
     val initResult = Await(init, 30.seconds)
     var cursorId:String = initResult.getCursorId
     while (!cursorId.isEmpty) {
        val futures:Seq[Future] = client.grabWithSize(cursorId).map{response=>
            response.getAllResults.map(result=>
                val grabbedOne:Future[Entity] = client.grabOneEntity(result.id) //request over network
                val resultMap:Map[String,Any] = buildMap(result)
                val transformed:Map[String,Any] = transform(resultMap) //no future here
                grabbedOne.map{grabbedOne=>
                    buildMap(grabbedOne) == transformed
                }
            }
        Futures.sequence(futures).map(_=> response.getNewCursorId)
        }
     }
    
     def buildMap(...):Map[String,Any] //sync call
    

    我注意到如果我增加两次大小,while中的每次迭代都开始慢慢运行~1.5。但我没有看到我的PC处理器加载更多。它加载到零附近,但时间增加~1.5。为什么?我已经设定了:

    implicit val ec = ExecutionContext.fromExecutor(Executors.newFixedThreadPool(1024))
    

    我认为,并非所有期货都是并行执行的。但为什么?还有什么要修好的?

1 个答案:

答案 0 :(得分:1)

我在您的代码中看到Futures没有阻止对方。数据库更可能是瓶颈。

是否可以在数据库调用方面为O(1)而不是O(n)进行SQL连接? (如果您正在使用Slick,请查看queries section关于联接的内容。)

如果负载较低,可能是连接池最大化,您需要为数据库和网络增加连接池。