Skip to content

u3qb_sort use quicksort#851

Merged
pkova merged 6 commits into
next/kelvin/409from
dozreg/quicksort
Aug 11, 2025
Merged

u3qb_sort use quicksort#851
pkova merged 6 commits into
next/kelvin/409from
dozreg/quicksort

Conversation

@dozreg-toplud

Copy link
Copy Markdown
Contributor

Implements +sort jet by building an array of nouns to run quicksort algorithm on. Has much better memory usage for large lists and appears to be faster than the previous implementation: ~:(sort (gulf 1 100.000) gth) used to run out of memory, but not anymore, and ~:(sort (gulf 1 10.000) gth) runs about 2x faster.

@dozreg-toplud dozreg-toplud requested a review from a team as a code owner July 29, 2025 09:06
@dozreg-toplud dozreg-toplud requested a review from pkova July 29, 2025 09:06
@dozreg-toplud

Copy link
Copy Markdown
Contributor Author

dont merge it yet, I didnt check for stability

@dozreg-toplud

Copy link
Copy Markdown
Contributor Author

+sort reverses the list if comparison gate always returns yes, and preserves the order if it always returns no. is this intentional?

@dozreg-toplud

Copy link
Copy Markdown
Contributor Author

rewrote the jet to use merge sort for stability. Notice the reversed comparison here:

// reversed comparison to mimick order reversal of pivot
// and compared element in Hoon
//
u3_noun sam = u3nc(u3k(arr_u[j_w]), u3k(arr_u[i_w]));
u3_noun hoz = u3j_gate_slam(sit_u, sam);
if ( hoz > 1 ) u3m_bail(c3__exit);
if ( c3n == hoz )
tmp_u[k_w++] = arr_u[i_w++];
else
tmp_u[k_w++] = arr_u[j_w++];
}

This is done in order to mimick the behavior of +sort function in Hoon, where the first element of the array is taken as a pivot and then it is passed to the comparator gate as a second argument, the first being the compared list element.

@dozreg-toplud

Copy link
Copy Markdown
Contributor Author

tested sort correctness with this dojo expression:

=/  gat1  |=([[@ v1=@] @ v2=@] (lte v1 v2))
=/  gat2  |=([[@ v1=@] @ v2=@] (lth v1 v2))
!.  ^-  ~
=/  one-done  |
=/  gat=$-([[@ @] @ @] ?)  gat1
|-  ^-  ~
=*  gat-loop  $
=*  vals-num  5
=*  len-list  10
=/  perm  (pow vals-num len-list)
|-  ^-  ~
=*  perm-loop  $
?:  =(perm 0)
  ?:  one-done  ~
  gat-loop(gat gat2, one-done &)
=/  l=(list (pair @ @))  ::  idx and value
  =/  c  len-list
  |-  ^-  (list (pair @ @))
  =*  list-loop  $
  ?:  =(c 0)  ~
  :-  [(sub len-list c) (mod perm vals-num)]
  list-loop(c (dec c), perm (div perm vals-num))
::
=/  l1  (sort l gat)
=/  l2  .*([-:sort [l gat] +>:sort] -:sort)
?.  =(l1 l2)
  ~|  ^-  (list [@ @])  l1
  ~|  ;;  (list [@ @])  l2
  !!
~?  =(0 (mod perm 10.000))  perm
perm-loop(perm (dec perm))

Changing comparison in sort jet to

u3_noun sam = u3nc(u3k(arr_u[i_w]), u3k(arr_u[j_w]));
c3_o hoz_o = u3x_loob(u3j_gate_slam(sit_u, sam));
if ( c3y == hoz_o )
//  ...

would make the expression fail

@pkova pkova merged commit 4e5930b into next/kelvin/409 Aug 11, 2025
2 checks passed
@pkova pkova deleted the dozreg/quicksort branch August 11, 2025 15:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants