Skip to content

Instantly share code, notes, and snippets.

@line-o
Last active May 13, 2020 20:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save line-o/86780e0d37e62c62a0241d6db935b8bf to your computer and use it in GitHub Desktop.
Save line-o/86780e0d37e62c62a0241d6db935b8bf to your computer and use it in GitHub Desktop.
xquery version "3.1";
import module namespace xbow="http://line-o.de/xq/xbow";
let $length := 100000
let $sequence-of-maps := (1 to $length) ! map { "n": ., "values": ("a" || util:random(100), "b" || util:random(100), "c" || util:random(100)) }
let $keyed-sequence :=
for-each($sequence-of-maps, function ($item) {
map:put($item, "key", string-join($item?values))
})
return xbow:groupBy($keyed-sequence, xbow:pluck("key"))
=> map:for-each(function ($k, $v) {
if (count($v) > 1) then array{$v} else ()
})
xquery version "3.1";
(:import module namespace xbow="http://line-o.de/xq/xbow";:)
declare variable $local:millisecond := xs:dayTimeDuration('PT0.001S');
declare variable $local:json := json-doc("/db/items.json");
declare function local:reducer ($result, $item) {
let $key := $item?key
let $value := ($result($key), $item)
return map:put($result, $key, $value)
};
declare function local:filter ($k, $v) {
if (count($v) gt 1)
then array{$v}
else ()
};
declare function local:find-matches-hof ($items as map(*)*) {
(: xbow:groupBy($items, xbow:pluck("key")):)
fold-left($items, map {}, local:reducer#2)
=> map:for-each(local:filter#2)
};
declare function local:find-matches-flwor ($items as map(*)*) {
for $i in $items
group by $key := $i?key
where count($i) gt 1
return
array { $i }
};
declare function local:add-keys ($items as map(*)*) {
for-each($items, function ($item) {
map:put($item, "key", string-join($item?values, " "))
})
};
declare function local:run-tests (
$length as xs:integer, $iterations as xs:integer, $function as function(*)) {
let $seq-keyed :=
$local:json
=> array:subarray(1, $length)
=> array:flatten()
=> local:add-keys()
let $tests :=
fold-left(1 to $iterations, [],
function ($result, $next) {
let $start := util:system-time()
let $run := $function($seq-keyed)
let $duration := (util:system-time() - $start) div $local:millisecond
return array:append($result, $duration)
})
let $results := map {
"length": $length,
"test-count": $iterations,
"average-duration": avg($tests?*),
"durations": $tests
}
return (
util:log("INFO", $results),
$results
)
};
let $iterations := 5
let $lengths := (
100, 200, 300, 400, 500, 750, 1000,
1250, 1500, 1750, 2000, 2500, 3000, 4000,
5000, 7500, 10000, 15000,
20000, 30000, 40000, 50000,
75000, 100000
)
(:let $function := local:find-matches-hof#1:)
let $function := local:find-matches-flwor#1
let $runner := local:run-tests(?, $iterations, $function)
return
array { for-each($lengths, $runner) }
xquery version "3.1";
import module namespace xbow="http://line-o.de/xq/xbow";
let $length := 100000
let $sequence-of-maps := (1 to $length) ! map { "n": ., "values": ("a" || util:random(100), "b" || util:random(100), "c" || util:random(100)) }
let $key-func := function ($item) { string-join($item?values) }
let $start := util:system-time()
let $run :=
xbow:groupBy($sequence-of-maps, $key-func)
=> map:for-each(function ($k, $v) {
if (count($v) > 1) then array{$v} else ()
})
return (util:system-time() - $start) div xs:dayTimeDuration('PT0.001S')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment