So the performance of this only surpasses list when you approach 100 items (and that is not including the need to traverse through the linked list to find the insertion point) so this might be the last commit
This commit is contained in:
		
							
								
								
									
										113
									
								
								test/benchmark.gleam
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								test/benchmark.gleam
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,113 @@
 | 
			
		||||
import dllist
 | 
			
		||||
import gleam/list
 | 
			
		||||
import glychee/benchmark
 | 
			
		||||
import glychee/configuration
 | 
			
		||||
 | 
			
		||||
@target(erlang)
 | 
			
		||||
pub fn main() {
 | 
			
		||||
  configuration.initialize()
 | 
			
		||||
  configuration.set_pair(configuration.Warmup, 2)
 | 
			
		||||
  configuration.set_pair(configuration.Parallel, 2)
 | 
			
		||||
 | 
			
		||||
  benchmark2()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@target(erlang)
 | 
			
		||||
fn benchmark() {
 | 
			
		||||
  benchmark.run(
 | 
			
		||||
    [
 | 
			
		||||
      benchmark.Function(
 | 
			
		||||
        label: "list append",
 | 
			
		||||
        callable: fn(data: #(List(Int), Int)) {
 | 
			
		||||
          fn() {
 | 
			
		||||
            list.fold(data.0, [], fn(acc, i) { [i, ..acc] })
 | 
			
		||||
            |> list.reverse
 | 
			
		||||
            |> insert_at(data.1, 999)
 | 
			
		||||
            Nil
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
      ),
 | 
			
		||||
      benchmark.Function(
 | 
			
		||||
        label: "dllist insert",
 | 
			
		||||
        callable: fn(data: #(List(Int), Int)) {
 | 
			
		||||
          fn() {
 | 
			
		||||
            list.fold(data.0, dllist.new(), fn(acc, i) { dllist.insert(acc, i) })
 | 
			
		||||
            |> move_left_n(data.1)
 | 
			
		||||
            |> dllist.insert(999)
 | 
			
		||||
            Nil
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
      ),
 | 
			
		||||
    ],
 | 
			
		||||
    [
 | 
			
		||||
      benchmark.Data(label: "6 Items", data: #(list.range(1, 6), 3)),
 | 
			
		||||
      benchmark.Data(label: "10 Items", data: #(list.range(1, 10), 5)),
 | 
			
		||||
      benchmark.Data(label: "100 Items", data: #(list.range(1, 100), 50)),
 | 
			
		||||
    ],
 | 
			
		||||
  )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@target(erlang)
 | 
			
		||||
fn benchmark2() {
 | 
			
		||||
  benchmark.run(
 | 
			
		||||
    [
 | 
			
		||||
      benchmark.Function(
 | 
			
		||||
        label: "list append",
 | 
			
		||||
        callable: fn(data: #(List(Int), dllist.DLList(Int), Int)) {
 | 
			
		||||
          fn() {
 | 
			
		||||
            let _ = insert_at(data.0, data.2, 999)
 | 
			
		||||
            Nil
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
      ),
 | 
			
		||||
      benchmark.Function(
 | 
			
		||||
        label: "dllist insert",
 | 
			
		||||
        callable: fn(data: #(List(Int), dllist.DLList(Int), Int)) {
 | 
			
		||||
          fn() {
 | 
			
		||||
            let _ = dllist.insert(data.1, 999)
 | 
			
		||||
            Nil
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
      ),
 | 
			
		||||
    ],
 | 
			
		||||
    [
 | 
			
		||||
      benchmark.Data(label: "6 Items", data: #(
 | 
			
		||||
        list.range(1, 6),
 | 
			
		||||
        dllist.from_list(list.range(1, 6)) |> move_left_n(3),
 | 
			
		||||
        3,
 | 
			
		||||
      )),
 | 
			
		||||
      benchmark.Data(label: "10 Items", data: #(
 | 
			
		||||
        list.range(1, 10),
 | 
			
		||||
        dllist.from_list(list.range(1, 10)) |> move_left_n(5),
 | 
			
		||||
        5,
 | 
			
		||||
      )),
 | 
			
		||||
      benchmark.Data(label: "100 Items", data: #(
 | 
			
		||||
        list.range(1, 100),
 | 
			
		||||
        dllist.from_list(list.range(1, 100)) |> move_left_n(50),
 | 
			
		||||
        50,
 | 
			
		||||
      )),
 | 
			
		||||
      benchmark.Data(label: "1000 Items", data: #(
 | 
			
		||||
        list.range(1, 1000),
 | 
			
		||||
        dllist.from_list(list.range(1, 1000)) |> move_left_n(500),
 | 
			
		||||
        500,
 | 
			
		||||
      )),
 | 
			
		||||
      benchmark.Data(label: "10000 Items", data: #(
 | 
			
		||||
        list.range(1, 10_000),
 | 
			
		||||
        dllist.from_list(list.range(1, 10_000)) |> move_left_n(5000),
 | 
			
		||||
        5000,
 | 
			
		||||
      )),
 | 
			
		||||
    ],
 | 
			
		||||
  )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn insert_at(list: List(a), pos: Int, value: a) -> List(a) {
 | 
			
		||||
  let #(l1, l2) = list.split(list, pos)
 | 
			
		||||
  list.append(l1, [value, ..l2])
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn move_left_n(list: dllist.DLList(a), n: Int) -> dllist.DLList(a) {
 | 
			
		||||
  case n {
 | 
			
		||||
    0 -> list
 | 
			
		||||
    n -> move_left_n(dllist.move_left(list), n - 1)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,10 +1,22 @@
 | 
			
		||||
import dllist
 | 
			
		||||
import gleam/dict
 | 
			
		||||
import startest
 | 
			
		||||
 | 
			
		||||
pub fn main() -> Nil {
 | 
			
		||||
  startest.run(startest.default_config())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn new_tests() {
 | 
			
		||||
  startest.describe("new instance", [
 | 
			
		||||
    startest.it("terminated list", fn() {
 | 
			
		||||
      assert dllist.new() == dllist.DLList(1, 0, dict.from_list([]))
 | 
			
		||||
    }),
 | 
			
		||||
    startest.it("cyclic list", fn() {
 | 
			
		||||
      assert dllist.new_cyclic() == dllist.CyclicList(1, 0, dict.from_list([]))
 | 
			
		||||
    }),
 | 
			
		||||
  ])
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn is_empty_tests() {
 | 
			
		||||
  startest.describe("is_emtpy", [
 | 
			
		||||
    startest.it("terminated list", fn() {
 | 
			
		||||
@@ -19,3 +31,31 @@ pub fn is_empty_tests() {
 | 
			
		||||
    }),
 | 
			
		||||
  ])
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn from_list_tests() {
 | 
			
		||||
  startest.describe("from_list", [
 | 
			
		||||
    startest.it("terminated list", fn() {
 | 
			
		||||
      assert dllist.is_empty(dllist.from_list([]))
 | 
			
		||||
 | 
			
		||||
      assert !dllist.is_empty(dllist.from_list([1]))
 | 
			
		||||
 | 
			
		||||
      assert dllist.from_list([1]) |> dllist.get == Ok(1)
 | 
			
		||||
      assert dllist.from_list([1, 2, 3, 4]) |> dllist.get == Ok(4)
 | 
			
		||||
 | 
			
		||||
      assert dllist.from_list([1]) |> dllist.to_list == [1]
 | 
			
		||||
      assert dllist.from_list([1, 2, 3, 4]) |> dllist.to_list == [1, 2, 3, 4]
 | 
			
		||||
    }),
 | 
			
		||||
    startest.it("cyclic list", fn() {
 | 
			
		||||
      assert dllist.is_empty(dllist.from_list_cyclic([]))
 | 
			
		||||
 | 
			
		||||
      assert !dllist.is_empty(dllist.from_list_cyclic([1]))
 | 
			
		||||
 | 
			
		||||
      assert dllist.from_list_cyclic([1]) |> dllist.get == Ok(1)
 | 
			
		||||
      assert dllist.from_list_cyclic([1, 2, 3, 4]) |> dllist.get == Ok(4)
 | 
			
		||||
 | 
			
		||||
      assert dllist.from_list_cyclic([1]) |> dllist.to_list == [1]
 | 
			
		||||
      assert dllist.from_list_cyclic([1, 2, 3, 4]) |> dllist.to_list
 | 
			
		||||
        == [4, 1, 2, 3]
 | 
			
		||||
    }),
 | 
			
		||||
  ])
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user