-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Closed
Labels
Description
The following function uses "reduce" to emit the "equilibrium indices" of the input array. An equivalent version written using recurse or foreach runs nicely in jq>1.4 (i.e. those versions that have TCO and foreach), but in both jq 1.4 and jq>1.4, the version using reduce has roughly exponentially worse performance in the length of the input array.
Here are some gross timings using jq>1.4 (i.e. based simply on "time jq ...") for the following query:
array(N;0) | equilibrium_indices | length
# N (u+s in seconds)
#1000 0.19
# 1e4 0.43
# 2e4 1.54
# 3e4 3.43
# 4e4 6.2
# 5e4 10.4
# 6e4 16.5
Since the recurse
and foreach
versions of this program are fine in jq>1,4, the problem is evidently with the implementation of "reduce". Hopefully a skilled eye will be able to identify it; if not, then maybe "reduce" should be implemented using "foreach"!
def equilibrium_indices:
def indices(a):
reduce range(0;a|length) as $i
# state: [ headsum, tailsum, answers]
( [ 0, add, [] ];
.[0] as $h
| (.[1] - a[$i]) as $t
| (if $h == $t then .[2] + [$i] else .[2] end) as $ans
| [ $h + a[$i], $t, $ans ] )
| .[2];
. as $in | indices($in);
def array(n;init): reduce range(0;n) as $i ([]; . + [init]);