0

if I have the following with ls an instance of scala.collection.immutable.List :

will ls.init make a copy of the first n-1 elements of ls and then give this copy back thus yielding a runtime of theta of n-1(because of the copy runtime)?

Does ls.tail take O(1) (I imagine this would deconstruct ls into head :: tail and then give back tail which would take O(1) given it's a single-linked-list)?

I actually need a collection that would give me O(1) init operation is there one that provides such running time for init?

Ali Dehghani
  • 46,221
  • 15
  • 164
  • 151
Simonlbc
  • 591
  • 1
  • 4
  • 16
  • 2
    Yes, and yes. `Vector.dropRight(1)` is O(1). – Dima Jan 11 '16 at 15:08
  • There is is quite a useful chart for the performance of collections here: http://docs.scala-lang.org/overviews/collections/performance-characteristics.html – Hamish Jan 11 '16 at 15:10
  • you could consider using lists in reverse order, then you could use tail instead of `init` (if that is possible) – Łukasz Jan 11 '16 at 15:10

1 Answers1

1

About tail:

@SerialVersionUID(509929039250432923L) // value computed by serialver for 2.11.2, annotation added in 2.11.4
final case class ::[B](override val head: B, private[scala] var tl: List[B]) extends List[B] {
  override def tail : List[B] = tl
  override def isEmpty: Boolean = false
}

So yes, it's O(1). Init is defined in TraversableLike:

def init: Repr = {
    if (isEmpty) throw new UnsupportedOperationException("empty.init")
    var lst = head
    var follow = false
    val b = newBuilder
    b.sizeHint(this, -1)
    for (x <- this) {
      if (follow) b += lst
      else follow = true
      lst = x
    }
    b.result
}

So it's linear.

If you need immutable structure with constant init there is a Vector as @Dima mentioned. Init is implemented as dropRight(1) there. But it's "effectively constant" as Vector is more like a deep array of arrays (Trie of 32), so dropRight is practically making a new view with another size (by quickly copying on some high level), but still has to process the right edge in smart way, so this "1" might be actually 32, or even 64 (I suppose).

dk14
  • 22,206
  • 4
  • 51
  • 88
  • `O(1) === O(64)`, it is the same exact thing. – Dima Jan 11 '16 at 15:38
  • @DIma I'm aware of that, that's why it's called effectively constant :) – dk14 Jan 11 '16 at 15:39
  • 2
    @Dima sometimes the real number of operations matters in practice (1ms vs 32ms), so I think the info about how exactly it executes might be useful as well. – dk14 Jan 11 '16 at 15:41
  • the info about how it executes may be useful ... But saying it is O(32) is not. – Dima Jan 11 '16 at 16:46
  • @Dima I never said that! – dk14 Jan 11 '16 at 16:46
  • @Dima actually even your first comment is not precisely correct as there is no such thing as O(64) – dk14 Jan 11 '16 at 16:50
  • What do you mean "there is no such thing"? Sure, there is. It is the same thing as O(1). And yes, you did say it: "so this "1" might be actually 32, or even 64 (I suppose)." – Dima Jan 11 '16 at 17:06
  • And where did you see the `O` in my sentence, ha? I was talking about number of operations obviously. Answering about `O(32)`, equality of O is asymmetric, so no one "ever" uses O(100500) notation in scientific publications. O is usually defined in term of simpler functions than the one analized, so the `1` denotion is used to say that there is a constant, it could be C, so defining complexity as O(32) is like saying that integral of `0dx` = 5. Otherwise, you would have to deal with O(1) <== O(32), but O(32) <!= O(1), so how it could be a same exact thing then? – dk14 Jan 12 '16 at 04:36
  • Well, "1" is your sentence wasn't the number of comparisons, was it? I doubt, that appending an element to a vector involves any comparisons, regardless of implementation. "Noone ever uses O(100500)" exactly for the reason I mentioned above: it is the same thing as O(1). – Dima Jan 12 '16 at 11:42
  • It was number of operations. I think this conversation has no point as either I don't understand you or you just don't read it carefully. Either way, you're free to edit my answer or write your own if you've got something to say in formal way – dk14 Jan 12 '16 at 12:41
  • The point is that "1" in "O(1)" is *not* the number of operations. – Dima Jan 12 '16 at 14:55
  • And I never said that it is. Read carefully! Читайте уважно! This conversation is over. – dk14 Jan 12 '16 at 15:39
  • I do read carefully (and I am not Ukrainian). You said exactly this: "t was number of operations." just one line above, referring to you earlier statement, that you have now deleted: "so this "1" might be actually 32, or even 64 (I suppose)". I appreciate that you recognized that that statement was erroneous and removed it, but having retracted a statement is still not the same as to "never say it". – Dima Jan 12 '16 at 16:41