From 6ded6738ff5004fce014e08748a39fd1ad4908ad Mon Sep 17 00:00:00 2001 From: Justin Lin Date: Fri, 5 Mar 2021 20:07:14 +0800 Subject: [PATCH] performance improved --- src/util/_impl/_dedup_impl.scad | 43 +++++++++++++++------------------ src/util/dedup.scad | 19 +++++++++++++-- 2 files changed, 36 insertions(+), 26 deletions(-) diff --git a/src/util/_impl/_dedup_impl.scad b/src/util/_impl/_dedup_impl.scad index 35c35d89..595b56df 100644 --- a/src/util/_impl/_dedup_impl.scad +++ b/src/util/_impl/_dedup_impl.scad @@ -1,27 +1,22 @@ -use <../some.scad> ; -function _dedup_sorted(lt, leng, eq) = - leng == 0 ? lt : - is_function(eq) ? - concat( - [lt[0]], - [for(i = [1:leng - 1]) if(!eq(lt[i], lt[i - 1])) lt[i]] - ) : - concat( - [lt[0]], - [for(i = [1:leng - 1]) if(lt[i] != lt[i - 1]) lt[i]] - ); +use <../slice.scad>; +use <../some.scad>; -function _dedup_vt(src, dest, leng, i = 0) = - i == leng ? dest : - // src[i] in dest ? - search([src[i]], dest) != [[]] ? _dedup_vt(src, dest, leng, i + 1) : - _dedup_vt(src, concat(dest, [src[i]]), leng, i + 1); +function _dedup(elems, leng, buckets, eq, hash, bucket_numbers, i = 0) = + i == leng ? buckets : + _dedup(elems, leng, _dedup_add(buckets, [i, elems[i]], eq, hash, bucket_numbers), eq, hash, bucket_numbers, i + 1); -function _dedup_eq(src, dest, eq, leng, i = 0) = - i == leng ? dest : - some(dest, function(el) eq(el, src[i])) ? _dedup_eq(src, dest, eq, leng, i + 1) : - _dedup_eq(src, concat(dest, [src[i]]), eq, leng, i + 1); - -function _dedup(src, dest, leng, eq) = - is_function(eq) ? _dedup_eq(src, dest, eq, leng) : _dedup_vt(src, dest, leng); \ No newline at end of file +function _dedup_add(buckets, i_elem, eq, hash, bucket_numbers) = + let( + i = i_elem[0], + elem = i_elem[1], + b_idx = hash(elem) % bucket_numbers, + bucket = buckets[b_idx] + ) + len(bucket) == 0 ? concat(slice(buckets, 0, b_idx), [[i_elem]], slice(buckets, b_idx + 1)) : + some(bucket, function(i_e) eq(i_e[1], elem)) ? buckets : + concat( + slice(buckets, 0, b_idx), + [concat(bucket, [i_elem])], + slice(buckets, b_idx + 1) + ); \ No newline at end of file diff --git a/src/util/dedup.scad b/src/util/dedup.scad index bfb9a50e..b87a7252 100644 --- a/src/util/dedup.scad +++ b/src/util/dedup.scad @@ -8,7 +8,22 @@ * **/ +use <../__comm__/_str_hash.scad>; use <_impl/_dedup_impl.scad>; +use ; -function dedup(lt, sorted = false, eq) = - sorted ? _dedup_sorted(lt, len(lt), eq) : _dedup(lt, [], len(lt), eq); \ No newline at end of file +function dedup(lt, eq = function(e1, e2) e1 == e2, hash = function(e) _str_hash(e)) = + lt == [] ? [] : + let( + leng_lt = len(lt), + bucket_numbers = ceil(sqrt(leng_lt)), + buckets = [for(i = [0:bucket_numbers - 1]) []], + deduped = _dedup(lt, leng_lt, buckets, eq, hash, bucket_numbers), + i_elem_lt = [ + for(bucket = deduped) + for(i_elem = bucket) + i_elem + ], + sorted = sort(i_elem_lt, by = function(e1, e2) e1[0] - e2[0]) + ) + [for(i_elem = sorted) i_elem[1]];