Skip to content

Add efficient functions to create sets from lists or arrays #4986

Closed
@vicuna

Description

@vicuna

Original bug ID: 4986
Reporter: @alainfrisch
Status: resolved (set by @alainfrisch on 2013-07-09T11:02:47Z)
Resolution: open
Priority: normal
Severity: feature
Fixed in version: 4.02.0+dev
Category: ~DO NOT USE (was: OCaml general)
Monitored by: mehdi @hcarty

Bug description

Creating a set from a list or an array is quite common. It could be useful
to add such functions in the Set module.

A trivial implementation is:

let of_array a =
Array.fold_right add a empty

A more efficient implementation is to sort the array first, and then build the balanced tree directly:

let of_sorted_array a =
  let rec sub i0 = function
    | 0 -> Empty
    | 1 -> Node (Empty, a.(i0), Empty, 1)
    | 2 -> Node (Node(Empty, a.(i0), Empty, 1), a.(i0 + 1), Empty, 2)
    | 3 -> Node (Node(Empty, a.(i0), Empty, 1), a.(i0 + 1), Node(Empty, a.(i0 + 2), Empty, 1), 2)
    | n ->
        let nl = n / 2 in
        let l = sub i0 nl in
        let r = sub (i0 + nl + 1) (n - nl - 1) in
        create l a.(i0 + nl) r
  in
  sub 0 (Array.length a)

(The cases for n=1,2,3 are just extra optimizations.)

When creating sets from arrays of random integers of size 100000,
the optimized version is almost twice as fast as the naive one (ocamlopt, x86).

File attachments

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions