splitAt函数在向量上的性能

时间:2015-08-12 00:50:01

标签: scala

vector上的大多数操作都是有效的,因为它的trie表示。但是,我无法弄清楚splitAt实施的性能配置文件是什么。

它在库中定义为:

override /*IterableLike*/ def splitAt(n: Int): (Vector[A], Vector[A]) = (take(n), drop(n))

take函数具有以下定义:

  override def take(n: Int): Vector[A] = {
    if (n <= 0)
      Vector.empty
    else if (startIndex + n < endIndex)
      dropBack0(startIndex + n)
    else
      this
  }

dropBack0具有以下定义:

  private def dropBack0(cutIndex: Int): Vector[A] = {
    val blockIndex = (cutIndex - 1) & ~31
    val xor = startIndex ^ (cutIndex - 1)
    val d = requiredDepth(xor)
    val shift = (startIndex & ~((1 << (5*d))-1))    
    val s = new Vector(startIndex-shift, cutIndex-shift, blockIndex-shift)
    s.initFrom(this)
    s.dirty = dirty
    s.gotoPosWritable(focus, blockIndex, focus ^ blockIndex)
    s.preClean(d)
    s.cleanRightEdge(cutIndex-shift)
    s
  }

正如你所看到的,dropBack0做了一些非常复杂的手术。

splitAt是否具有有效的持续性能还是更差?它似乎是有效的。

2 个答案:

答案 0 :(得分:4)

它实际上是不变的。向量是具有分支因子32的树。public boolean sendMessage(String message) { PrintWriter out = null; try { out = new PrintWriter( clientSocket.getOutputStream(), true ); Log.i( "MY_TAG", "SOCKET OPERATOR SENDING MESSAGE: " + message ); } catch (IOException e) { e.printStackTrace(); Log.i( "MY_TAG", "SOCKET OPERATOR FAILEDD TO SEND MESSAGE WITH EXCEPTION: " + e.getMessage() ); return false; } out.println(message); return true; } take操作在o中执行(log 32 N * 32)。由于树的高度不能超过5,因此在最坏的情况下droptakedrop的操作次数将为5 * 32 = 160。

答案 1 :(得分:3)

是的,如果您遵循dropBack0中调用的每个方法,则所有方法都需要恒定或有效的常量(最大数组大小为32)时间。