Reputation: 1783
I'm reading Purely Functional Data Structures written by Chris Okasaki.
In chapter 6, the book introduces lazy evaluation to us, I compared the two version
(*
https://github.com/mmottl/pure-fun/blob/master/chp5.ml#L47
*)
module BatchedQueue : QUEUE = struct
type 'a queue = 'a list * 'a list
let empty = [], []
let is_empty (f, _) = f = []
let checkf (f, r as q) = if f = [] then List.rev r, f else q
let snoc (f, r) x = checkf (f, x :: r)
let head = function [], _ -> raise Empty | x :: _, _ -> x
let tail = function [], _ -> raise Empty | _ :: f, r -> checkf (f, r)
end
And the lazy version would be:
(*
https://github.com/mmottl/pure-fun/blob/master/chp6.ml#L128
*)
module BankersQueue : QUEUE = struct
type 'a queue = int * 'a stream * int * 'a stream
let empty = 0, lazy Nil, 0, lazy Nil
let is_empty (lenf, _, _, _) = lenf = 0
let check (lenf, f, lenr, r as q) =
if lenr <= lenf then q
else (lenf + lenr, f ++ reverse r, 0, lazy Nil)
let snoc (lenf, f, lenr, r) x =
check (lenf, f, lenr + 1, lazy (Cons (x, r)))
let head = function
| _, lazy Nil, _, _ -> raise Empty
| _, lazy (Cons (x, _)), _, _ -> x
let tail = function
| _, lazy Nil, _, _ -> raise Empty
| lenf, lazy (Cons (_, f')), lenr, r -> check (lenf - 1, f', lenr, r)
end
These two version are very similar, check
function both needed to reverse the list, which is O(n) in theory.
It seems that both the version has the same time complexity, I'm wondering what's the advantage using lazy evaluation in Queue data structure?
Upvotes: 4
Views: 522
Reputation: 35210
Lazy version of check
function (and thus snoc
) is actually O(1), because it performs reverse using lazy operations, i.e., (++)
and reverse
are both lazy. That is the place where the credit is given. You start to pay when you take head
or tail
. Moreover, due to hidden mutability (and laziness is actually a variant of restricted mutability) you will pay for this credit only once, even if you have different futures. There is a very interesting blog post on bankers queue (and on a batch queue) that may help you to understand why this make difference.
Upvotes: 3