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:
@@ -18,3 +18,4 @@ gleam_stdlib = ">= 0.44.0 and < 2.0.0"
|
|||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
gleeunit = ">= 1.0.0 and < 2.0.0"
|
gleeunit = ">= 1.0.0 and < 2.0.0"
|
||||||
startest = ">= 0.7.0 and < 1.0.0"
|
startest = ">= 0.7.0 and < 1.0.0"
|
||||||
|
glychee = ">= 1.1.2 and < 2.0.0"
|
||||||
|
|||||||
@@ -3,8 +3,10 @@
|
|||||||
|
|
||||||
packages = [
|
packages = [
|
||||||
{ name = "argv", version = "1.0.2", build_tools = ["gleam"], requirements = [], otp_app = "argv", source = "hex", outer_checksum = "BA1FF0929525DEBA1CE67256E5ADF77A7CDDFE729E3E3F57A5BDCAA031DED09D" },
|
{ name = "argv", version = "1.0.2", build_tools = ["gleam"], requirements = [], otp_app = "argv", source = "hex", outer_checksum = "BA1FF0929525DEBA1CE67256E5ADF77A7CDDFE729E3E3F57A5BDCAA031DED09D" },
|
||||||
|
{ name = "benchee", version = "1.4.0", build_tools = ["mix"], requirements = ["deep_merge", "statistex", "table"], otp_app = "benchee", source = "hex", outer_checksum = "299CD10DD8CE51C9EA3DDB74BB150F93D25E968F93E4C1FA31698A8E4FA5D715" },
|
||||||
{ name = "bigben", version = "1.0.1", build_tools = ["gleam"], requirements = ["birl", "gleam_erlang", "gleam_otp", "gleam_stdlib"], otp_app = "bigben", source = "hex", outer_checksum = "190E489610A80D76C48BACC75EB8314BD184FF0220AB0F251ABE760B993B91BB" },
|
{ name = "bigben", version = "1.0.1", build_tools = ["gleam"], requirements = ["birl", "gleam_erlang", "gleam_otp", "gleam_stdlib"], otp_app = "bigben", source = "hex", outer_checksum = "190E489610A80D76C48BACC75EB8314BD184FF0220AB0F251ABE760B993B91BB" },
|
||||||
{ name = "birl", version = "1.8.0", build_tools = ["gleam"], requirements = ["gleam_regexp", "gleam_stdlib", "ranger"], otp_app = "birl", source = "hex", outer_checksum = "2AC7BA26F998E3DFADDB657148BD5DDFE966958AD4D6D6957DD0D22E5B56C400" },
|
{ name = "birl", version = "1.8.0", build_tools = ["gleam"], requirements = ["gleam_regexp", "gleam_stdlib", "ranger"], otp_app = "birl", source = "hex", outer_checksum = "2AC7BA26F998E3DFADDB657148BD5DDFE966958AD4D6D6957DD0D22E5B56C400" },
|
||||||
|
{ name = "deep_merge", version = "1.0.0", build_tools = ["mix"], requirements = [], otp_app = "deep_merge", source = "hex", outer_checksum = "CE708E5F094B9CD4E8F2BE4F00D2F4250C4095BE93F8CD6D018C753894885430" },
|
||||||
{ name = "exception", version = "2.1.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "exception", source = "hex", outer_checksum = "329D269D5C2A314F7364BD2711372B6F2C58FA6F39981572E5CA68624D291F8C" },
|
{ name = "exception", version = "2.1.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "exception", source = "hex", outer_checksum = "329D269D5C2A314F7364BD2711372B6F2C58FA6F39981572E5CA68624D291F8C" },
|
||||||
{ name = "filepath", version = "1.1.2", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "filepath", source = "hex", outer_checksum = "B06A9AF0BF10E51401D64B98E4B627F1D2E48C154967DA7AF4D0914780A6D40A" },
|
{ name = "filepath", version = "1.1.2", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "filepath", source = "hex", outer_checksum = "B06A9AF0BF10E51401D64B98E4B627F1D2E48C154967DA7AF4D0914780A6D40A" },
|
||||||
{ name = "gleam_community_ansi", version = "1.4.3", build_tools = ["gleam"], requirements = ["gleam_community_colour", "gleam_regexp", "gleam_stdlib"], otp_app = "gleam_community_ansi", source = "hex", outer_checksum = "8A62AE9CC6EA65BEA630D95016D6C07E4F9973565FA3D0DE68DC4200D8E0DD27" },
|
{ name = "gleam_community_ansi", version = "1.4.3", build_tools = ["gleam"], requirements = ["gleam_community_colour", "gleam_regexp", "gleam_stdlib"], otp_app = "gleam_community_ansi", source = "hex", outer_checksum = "8A62AE9CC6EA65BEA630D95016D6C07E4F9973565FA3D0DE68DC4200D8E0DD27" },
|
||||||
@@ -19,14 +21,17 @@ packages = [
|
|||||||
{ name = "gleam_yielder", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_yielder", source = "hex", outer_checksum = "8E4E4ECFA7982859F430C57F549200C7749823C106759F4A19A78AEA6687717A" },
|
{ name = "gleam_yielder", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_yielder", source = "hex", outer_checksum = "8E4E4ECFA7982859F430C57F549200C7749823C106759F4A19A78AEA6687717A" },
|
||||||
{ name = "gleeunit", version = "1.6.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "FDC68A8C492B1E9B429249062CD9BAC9B5538C6FBF584817205D0998C42E1DAC" },
|
{ name = "gleeunit", version = "1.6.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "FDC68A8C492B1E9B429249062CD9BAC9B5538C6FBF584817205D0998C42E1DAC" },
|
||||||
{ name = "glint", version = "1.2.1", build_tools = ["gleam"], requirements = ["gleam_community_ansi", "gleam_community_colour", "gleam_stdlib", "snag"], otp_app = "glint", source = "hex", outer_checksum = "2214C7CEFDE457CEE62140C3D4899B964E05236DA74E4243DFADF4AF29C382BB" },
|
{ name = "glint", version = "1.2.1", build_tools = ["gleam"], requirements = ["gleam_community_ansi", "gleam_community_colour", "gleam_stdlib", "snag"], otp_app = "glint", source = "hex", outer_checksum = "2214C7CEFDE457CEE62140C3D4899B964E05236DA74E4243DFADF4AF29C382BB" },
|
||||||
|
{ name = "glychee", version = "1.1.2", build_tools = ["gleam"], requirements = ["benchee"], otp_app = "glychee", source = "hex", outer_checksum = "41784216C213F223095BB3FC3EDDB60CC537835B2340A868EA3931193F7F3824" },
|
||||||
{ name = "ranger", version = "1.4.0", build_tools = ["gleam"], requirements = ["gleam_stdlib", "gleam_yielder"], otp_app = "ranger", source = "hex", outer_checksum = "C8988E8F8CDBD3E7F4D8F2E663EF76490390899C2B2885A6432E942495B3E854" },
|
{ name = "ranger", version = "1.4.0", build_tools = ["gleam"], requirements = ["gleam_stdlib", "gleam_yielder"], otp_app = "ranger", source = "hex", outer_checksum = "C8988E8F8CDBD3E7F4D8F2E663EF76490390899C2B2885A6432E942495B3E854" },
|
||||||
{ name = "simplifile", version = "2.3.0", build_tools = ["gleam"], requirements = ["filepath", "gleam_stdlib"], otp_app = "simplifile", source = "hex", outer_checksum = "0A868DAC6063D9E983477981839810DC2E553285AB4588B87E3E9C96A7FB4CB4" },
|
{ name = "simplifile", version = "2.3.0", build_tools = ["gleam"], requirements = ["filepath", "gleam_stdlib"], otp_app = "simplifile", source = "hex", outer_checksum = "0A868DAC6063D9E983477981839810DC2E553285AB4588B87E3E9C96A7FB4CB4" },
|
||||||
{ name = "snag", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "snag", source = "hex", outer_checksum = "7E9F06390040EB5FAB392CE642771484136F2EC103A92AE11BA898C8167E6E17" },
|
{ name = "snag", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "snag", source = "hex", outer_checksum = "7E9F06390040EB5FAB392CE642771484136F2EC103A92AE11BA898C8167E6E17" },
|
||||||
{ name = "startest", version = "0.7.0", build_tools = ["gleam"], requirements = ["argv", "bigben", "birl", "exception", "gleam_community_ansi", "gleam_erlang", "gleam_javascript", "gleam_regexp", "gleam_stdlib", "glint", "simplifile", "tom"], otp_app = "startest", source = "hex", outer_checksum = "71B9CB82C4B8779A4BD54C7151DF7D0B0F778D0DDE805B782B44EFA7BA8F50DA" },
|
{ name = "startest", version = "0.7.0", build_tools = ["gleam"], requirements = ["argv", "bigben", "birl", "exception", "gleam_community_ansi", "gleam_erlang", "gleam_javascript", "gleam_regexp", "gleam_stdlib", "glint", "simplifile", "tom"], otp_app = "startest", source = "hex", outer_checksum = "71B9CB82C4B8779A4BD54C7151DF7D0B0F778D0DDE805B782B44EFA7BA8F50DA" },
|
||||||
|
{ name = "statistex", version = "1.1.0", build_tools = ["mix"], requirements = [], otp_app = "statistex", source = "hex", outer_checksum = "F5950EA26AD43246BA2CCE54324AC394A4E7408FDCF98B8E230F503A0CBA9CF5" },
|
||||||
{ name = "tom", version = "2.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib", "gleam_time"], otp_app = "tom", source = "hex", outer_checksum = "74D0C5A3761F7A7D06994755D4D5AD854122EF8E9F9F76A3E7547606D8C77091" },
|
{ name = "tom", version = "2.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib", "gleam_time"], otp_app = "tom", source = "hex", outer_checksum = "74D0C5A3761F7A7D06994755D4D5AD854122EF8E9F9F76A3E7547606D8C77091" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[requirements]
|
[requirements]
|
||||||
gleam_stdlib = { version = ">= 0.44.0 and < 2.0.0" }
|
gleam_stdlib = { version = ">= 0.44.0 and < 2.0.0" }
|
||||||
gleeunit = { version = ">= 1.0.0 and < 2.0.0" }
|
gleeunit = { version = ">= 1.0.0 and < 2.0.0" }
|
||||||
|
glychee = { version = ">= 1.1.2 and < 2.0.0" }
|
||||||
startest = { version = ">= 0.7.0 and < 1.0.0" }
|
startest = { version = ">= 0.7.0 and < 1.0.0" }
|
||||||
|
|||||||
160
src/dllist.gleam
160
src/dllist.gleam
@@ -35,22 +35,26 @@ pub fn main() {
|
|||||||
|
|
||||||
// from_list([1, 2, 3, 4]) |> echo
|
// from_list([1, 2, 3, 4]) |> echo
|
||||||
|
|
||||||
let l1 = new() |> insert(1)
|
let l1 = new() |> insert(1) |> insert(2)
|
||||||
l1 |> echo
|
l1 |> echo
|
||||||
let l1t = take(l1, 5)
|
get(l1) |> echo
|
||||||
l1t |> echo
|
// let l1t = take(l1, 5)
|
||||||
let l2 = insert(l1, 2) |> move_left
|
// l1t |> echo
|
||||||
l2 |> echo
|
// let l2 = insert(l1, 2) |> move_left
|
||||||
let l2t = take(l2, 5)
|
// l2 |> echo
|
||||||
l2t |> echo
|
// let l2t = take(l2, 5)
|
||||||
|
// l2t |> echo
|
||||||
|
|
||||||
let l3 = insert(l2, 3)
|
// let l3 = insert(l2, 3)
|
||||||
l3 |> echo
|
// l3 |> echo
|
||||||
to_list(l3) |> echo
|
// to_list(l3) |> echo
|
||||||
// let l3t = take(l3, 7)
|
// let l3t = take(l3, 7)
|
||||||
// l3t |> echo
|
// l3t |> echo
|
||||||
// let l3t2 = take_rev(l3, 7)
|
// let l3t2 = take_rev(l3, 7)
|
||||||
// l3t2 |> echo
|
// l3t2 |> echo
|
||||||
|
// let l1 = new_cyclic() |> echo
|
||||||
|
// let l2 = l1 |> insert(1) |> insert(2) |> insert(3)
|
||||||
|
// to_list(l2) |> echo
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new() -> DLList(a) {
|
pub fn new() -> DLList(a) {
|
||||||
@@ -89,7 +93,12 @@ pub fn insert(list: DLList(a), val: a) -> DLList(a) {
|
|||||||
case is_empty(list) {
|
case is_empty(list) {
|
||||||
True -> {
|
True -> {
|
||||||
let node = Node(val, new_entry_ref, new_entry_ref)
|
let node = Node(val, new_entry_ref, new_entry_ref)
|
||||||
DLList(ref + 1, ref, dict.insert(list.mem, ref, node))
|
update_record(
|
||||||
|
list,
|
||||||
|
Some(ref + 1),
|
||||||
|
Some(ref),
|
||||||
|
Some(dict.insert(list.mem, ref, node)),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
False -> {
|
False -> {
|
||||||
let assert Ok(curr_node) = get_curr_node(list)
|
let assert Ok(curr_node) = get_curr_node(list)
|
||||||
@@ -110,11 +119,11 @@ pub fn insert(list: DLList(a), val: a) -> DLList(a) {
|
|||||||
}
|
}
|
||||||
Error(_) -> new_mem
|
Error(_) -> new_mem
|
||||||
}
|
}
|
||||||
|
update_record(
|
||||||
DLList(
|
list,
|
||||||
counter: list.counter + 1,
|
Some(list.counter + 1),
|
||||||
current: list.counter,
|
Some(list.counter),
|
||||||
mem: dict.insert(new_mem, ref, Node(val, list.current, next)),
|
Some(dict.insert(new_mem, ref, Node(val, list.current, next))),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -122,12 +131,23 @@ pub fn insert(list: DLList(a), val: a) -> DLList(a) {
|
|||||||
|
|
||||||
fn update_record(
|
fn update_record(
|
||||||
list: DLList(a),
|
list: DLList(a),
|
||||||
current: Int,
|
counter: Option(Int),
|
||||||
mem: dict.Dict(Int, Node(a)),
|
current: Option(Int),
|
||||||
|
mem: Option(dict.Dict(Int, Node(a))),
|
||||||
) -> DLList(a) {
|
) -> DLList(a) {
|
||||||
case list {
|
case list {
|
||||||
DLList(_, _, _) -> DLList(..list, current:, mem:)
|
DLList(_, _, _) ->
|
||||||
CyclicList(_, _, _) -> CyclicList(..list, current:, mem:)
|
DLList(
|
||||||
|
counter: option.unwrap(counter, list.counter),
|
||||||
|
current: option.unwrap(current, list.current),
|
||||||
|
mem: option.unwrap(mem, list.mem),
|
||||||
|
)
|
||||||
|
CyclicList(_, _, _) ->
|
||||||
|
CyclicList(
|
||||||
|
counter: option.unwrap(counter, list.counter),
|
||||||
|
current: option.unwrap(current, list.current),
|
||||||
|
mem: option.unwrap(mem, list.mem),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,44 +166,54 @@ pub fn delete(list: DLList(a)) -> DLList(a) {
|
|||||||
_, 0 -> {
|
_, 0 -> {
|
||||||
update_record(
|
update_record(
|
||||||
list,
|
list,
|
||||||
l,
|
None,
|
||||||
update_dict_entry(mem, l, fn(n) { Node(..n, right: r) }),
|
Some(l),
|
||||||
|
Some(update_dict_entry(mem, l, fn(n) { Node(..n, right: r) })),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
_, r if r == list.current -> {
|
_, r if r == list.current -> {
|
||||||
update_record(
|
update_record(
|
||||||
list,
|
list,
|
||||||
l,
|
None,
|
||||||
update_dict_entry(mem, l, fn(n) { Node(..n, right: l) }),
|
Some(l),
|
||||||
|
Some(update_dict_entry(mem, l, fn(n) { Node(..n, right: l) })),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
0, _ -> {
|
0, _ -> {
|
||||||
update_record(
|
update_record(
|
||||||
list,
|
list,
|
||||||
r,
|
None,
|
||||||
update_dict_entry(mem, r, fn(n) { Node(..n, left: l) }),
|
Some(r),
|
||||||
|
Some(update_dict_entry(mem, r, fn(n) { Node(..n, left: l) })),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
l, _ if l == list.current -> {
|
l, _ if l == list.current -> {
|
||||||
update_record(
|
update_record(
|
||||||
list,
|
list,
|
||||||
r,
|
None,
|
||||||
update_dict_entry(mem, r, fn(n) { Node(..n, left: r) }),
|
Some(r),
|
||||||
|
Some(update_dict_entry(mem, r, fn(n) { Node(..n, left: r) })),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
l, r if l == r -> {
|
l, r if l == r -> {
|
||||||
update_record(
|
update_record(
|
||||||
list,
|
list,
|
||||||
r,
|
None,
|
||||||
update_dict_entry(mem, r, fn(n) { Node(..n, left: r, right: r) }),
|
Some(r),
|
||||||
|
Some(
|
||||||
|
update_dict_entry(mem, r, fn(n) { Node(..n, left: r, right: r) }),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
_, _ -> {
|
_, _ -> {
|
||||||
update_record(
|
update_record(
|
||||||
list,
|
list,
|
||||||
r,
|
None,
|
||||||
update_dict_entry(mem, r, fn(n) { Node(..n, left: l) })
|
Some(r),
|
||||||
|
Some(
|
||||||
|
update_dict_entry(mem, r, fn(n) { Node(..n, left: l) })
|
||||||
|> update_dict_entry(l, fn(n) { Node(..n, right: r) }),
|
|> update_dict_entry(l, fn(n) { Node(..n, right: r) }),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -199,10 +229,9 @@ fn do_move_right(list: DLList(a)) -> Result(DLList(a), Nil) {
|
|||||||
case get_curr_node(list) {
|
case get_curr_node(list) {
|
||||||
Error(_) -> Error(Nil)
|
Error(_) -> Error(Nil)
|
||||||
Ok(node) -> {
|
Ok(node) -> {
|
||||||
case node.right, list {
|
case node.right {
|
||||||
0, _ -> Error(Nil)
|
0 -> Error(Nil)
|
||||||
r, DLList(_, _, _) -> Ok(DLList(..list, current: r))
|
r -> Ok(update_record(list, None, Some(r), None))
|
||||||
r, CyclicList(_, _, _) -> Ok(CyclicList(..list, current: r))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -217,10 +246,9 @@ fn do_move_left(list: DLList(a)) -> Result(DLList(a), Nil) {
|
|||||||
case get_curr_node(list) {
|
case get_curr_node(list) {
|
||||||
Error(_) -> Error(Nil)
|
Error(_) -> Error(Nil)
|
||||||
Ok(node) -> {
|
Ok(node) -> {
|
||||||
case node.left, list {
|
case node.left {
|
||||||
0, _ -> Error(Nil)
|
0 -> Error(Nil)
|
||||||
l, DLList(_, _, _) -> Ok(DLList(..list, current: l))
|
l -> Ok(update_record(list, None, Some(l), None))
|
||||||
l, CyclicList(_, _, _) -> Ok(CyclicList(..list, current: l))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -230,6 +258,10 @@ pub fn from_list(list: List(a)) -> DLList(a) {
|
|||||||
list.fold(list, new(), insert)
|
list.fold(list, new(), insert)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn from_list_cyclic(list: List(a)) -> DLList(a) {
|
||||||
|
list.fold(list, new_cyclic(), insert)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn take(list: DLList(a), n_times: Int) -> List(a) {
|
pub fn take(list: DLList(a), n_times: Int) -> List(a) {
|
||||||
take_loop(list, n_times, [])
|
take_loop(list, n_times, [])
|
||||||
}
|
}
|
||||||
@@ -280,7 +312,7 @@ pub fn to_list(list: DLList(a)) -> List(a) {
|
|||||||
DLList(_, _, _) -> DLList(..list, current: 1)
|
DLList(_, _, _) -> DLList(..list, current: 1)
|
||||||
CyclicList(_, _, _) -> list
|
CyclicList(_, _, _) -> list
|
||||||
}
|
}
|
||||||
to_list_loop(Ok(list), list.current, [])
|
to_list_loop(Ok(list), list.current, []) |> list.reverse
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_list_loop(
|
fn to_list_loop(
|
||||||
@@ -288,43 +320,35 @@ fn to_list_loop(
|
|||||||
start_ref: Int,
|
start_ref: Int,
|
||||||
acc: List(a),
|
acc: List(a),
|
||||||
) -> List(a) {
|
) -> List(a) {
|
||||||
case list {
|
case list |> echo {
|
||||||
Error(_) -> list.reverse(acc)
|
Error(_) -> acc
|
||||||
Ok(list) -> {
|
Ok(DLList(_, _, _) as list) -> {
|
||||||
case get(list) {
|
case get(list) {
|
||||||
Error(_) -> []
|
Error(_) -> []
|
||||||
Ok(val) -> to_list_loop(do_move_right(list), start_ref, [val, ..acc])
|
Ok(val) -> to_list_loop(do_move_right(list), start_ref, [val, ..acc])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Ok(CyclicList(_, _, _) as list) -> {
|
||||||
|
case get(list) {
|
||||||
|
Error(_) -> []
|
||||||
|
Ok(_) if start_ref == list.current && acc != [] -> acc
|
||||||
|
Ok(val) -> to_list_loop(do_move_right(list), start_ref, [val, ..acc])
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(list: DLList(a), value: a) -> Result(DLList(a), Nil) {
|
pub fn update(list: DLList(a), value: a) -> Result(DLList(a), Nil) {
|
||||||
use <- bool.guard(when: is_empty(list), return: Error(Nil))
|
use <- bool.guard(when: is_empty(list), return: Error(Nil))
|
||||||
case get_curr_node(list), list {
|
case get_curr_node(list) {
|
||||||
Error(_), _ -> Error(Nil)
|
Error(_) -> Error(Nil)
|
||||||
Ok(curr_node), DLList(_, _, _) ->
|
Ok(curr_node) ->
|
||||||
Ok(
|
Ok(update_record(
|
||||||
DLList(
|
list,
|
||||||
..list,
|
None,
|
||||||
mem: dict.insert(
|
None,
|
||||||
list.mem,
|
Some(dict.insert(list.mem, list.current, Node(..curr_node, val: value))),
|
||||||
list.current,
|
))
|
||||||
Node(..curr_node, val: value),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
Ok(curr_node), CyclicList(_, _, _) ->
|
|
||||||
Ok(
|
|
||||||
CyclicList(
|
|
||||||
..list,
|
|
||||||
mem: dict.insert(
|
|
||||||
list.mem,
|
|
||||||
list.current,
|
|
||||||
Node(..curr_node, val: value),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
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 dllist
|
||||||
|
import gleam/dict
|
||||||
import startest
|
import startest
|
||||||
|
|
||||||
pub fn main() -> Nil {
|
pub fn main() -> Nil {
|
||||||
startest.run(startest.default_config())
|
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() {
|
pub fn is_empty_tests() {
|
||||||
startest.describe("is_emtpy", [
|
startest.describe("is_emtpy", [
|
||||||
startest.it("terminated list", fn() {
|
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