Our server costs ~$56 per month to run. Please consider donating or becoming a Patron to help keep the site running. Help us gain new members by following us on Twitter and liking our page on Facebook!
Current time: April 27, 2024, 2:01 pm

Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
C++ "sort"
#28
RE: C++ "sort"
I've tried to make my program for sorting decimal numbers faster for nearly-sorted or nearly-reverse-sorted arrays by implementing the algorithm recursively, checking the sortedness of the array each iteration. I've implemented it in ArithmeticExpressionCompiler:
Code:
Syntax GAS ;Neka ArithmeticExpressionCompiler ispisuje asemblerski kod kompatibilan s GNU Assemblerom, da bude kompatibilan s GCC-om. Po defaultu ispisuje kod kompatibilan s FlatAssemblerom (a FlatAssembler na Linuxu ne radi bas najbolje).
verboseMode ON ;Neka ArithmeticExpressionCompiler ispisuje vise komentara u asemblerski kod koji ispisuje (da bude laksi za citanje i debuggiranje).
AsmStart ;Neka GNU Assembler obavijesti linkera da je "hybrid_sort" naziv potprograma...
   .global hybrid_sort
   hybrid_sort:
AsmEnd
If gornja_granica-donja_granica<2 ;Ako je niz duljine manje od 2 (0 ili 1), znaci da je vec poredan, pa prekidamo izvodenje ovog potprograma.
   AsmStart ;Kako radimo izvan sekcija, mozemo jednostavno prekinuti izvodenje potprograma asemblerskom naredbom "ret" (inace bismo, da radimo u sekcijama, morali znati vrti li se program na 32-bitnom ili 64-bitnom Linuxu).
       ret
   AsmEnd
EndIf
razvrstanost:=0
i:=donja_granica
While i < gornja_granica - 1
   razvrstanost:=razvrstanost+(originalni_niz[i]<originalni_niz[i+1])
   i:=i+1
EndWhile
razvrstanost:=razvrstanost/((gornja_granica-donja_granica-1)/2)-1
i:=2
While i<7 | i=7
   razvrstanost_na_potenciju[i] := pow(abs(razvrstanost), i) ;"pow(x,y)" je u AEC-u samo sintaksni secer za "exp(ln(x)*y)", i to vraca NaN za x=0 ili x<0. Nema ocitog nacina da se "pow(x,y)" prevede na asemblerski.
   razvrstanost_na_potenciju[i] := (razvrstanost=0) ? 0 : (mod(i,2)=1 & razvrstanost<0) ? (-razvrstanost_na_potenciju[i]) : razvrstanost_na_potenciju[i] ;C-ov i JavaScriptin uvjetni operator nekad zna znatno skratiti kod, zato sam ga ugradio i u svoj jezik.
   i:=i+1
EndWhile
;Formula koju je ispisao genetski algoritam za predvidanje koliko ce usporedbi QuickSort napraviti: https://github.com/FlatAssembler/ArithmeticExpressionCompiler/tree/master/QuickSort/Genetic_algorithm_for_deriving_the_formula
polinom_pod_apsolutnom := 2.38854*razvrstanost_na_potenciju[7] - 0.284258*razvrstanost_na_potenciju[6] - 1.87104*razvrstanost_na_potenciju[5] + 0.372637*razvrstanost_na_potenciju[4] + 0.167242*razvrstanost_na_potenciju[3] - 0.0884977*razvrstanost_na_potenciju[2] + 0.315119*razvrstanost
Eulerov_broj_na_koju_potenciju := (ln(gornja_granica - donja_granica) + ln(ln(gornja_granica - donja_granica))) * 1.05 + (ln(gornja_granica - donja_granica) - ln(ln(gornja_granica - donja_granica)) - ln(2)) * 0.9163 * abs(polinom_pod_apsolutnom)
koliko_usporedbi_ocekujemo_od_QuickSorta := exp(Eulerov_broj_na_koju_potenciju)
koliko_usporedbi_ocekujemo_od_MergeSorta := 2 * (gornja_granica - donja_granica) * ln(gornja_granica - donja_granica) / ln(2)
If razvrstanost=1 ;Ako je niz vec poredan.
   broj_vec_poredanih_podniza := broj_vec_poredanih_podniza + 1
   AsmStart
       ret
   AsmEnd
ElseIf razvrstanost = -1 ;Ako je niz obrnuto poredan...
   broj_obrnuto_poredanih_podniza := broj_obrnuto_poredanih_podniza + 1
   i:=donja_granica
   j:=gornja_granica-1
   While i<gornja_granica
       pomocni_niz[i] := originalni_niz[j]
       j := j - 1
       i := i + 1
   EndWhile
   i := donja_granica
   While i < gornja_granica
       originalni_niz[i] := pomocni_niz[i]
       i := i + 1
   EndWhile
   AsmStart
       ret
   AsmEnd
ElseIf koliko_usporedbi_ocekujemo_od_MergeSorta < koliko_usporedbi_ocekujemo_od_QuickSorta ;MergeSort algoritam (priblizno poredani podnizovi, za koje je MergeSort efikasniji od QuickSorta)...
   broj_pokretanja_MergeSorta := broj_pokretanja_MergeSorta + 1
   sredina_niza:=(gornja_granica+donja_granica)/2
   sredina_niza:=sredina_niza-mod(sredina_niza,1)
   vrh_stoga:=vrh_stoga+1 ;Zauzmi mjesta na stogu za rekurziju. Ne koristimo sistemski stog, kao sto koristi C++, nego koristimo vise globalnih polja kao stogove. Da koristimo sistemski stog, morali bismo znati pokrecemo li se na 32-bitnom Linuxu ili 64-bitnom Linuxu, jer oni nisu kompatibilni u tom pogledu.
   stog_s_donjim_granicama[vrh_stoga]:=donja_granica
   stog_s_gornjim_granicama[vrh_stoga]:=gornja_granica
   stog_sa_sredinama_niza[vrh_stoga]:=sredina_niza
   gornja_granica:=sredina_niza
   AsmStart
       call hybrid_sort
   AsmEnd
   donja_granica:=stog_s_donjim_granicama[vrh_stoga] ;Sad je rekurzija gotovo sigurno izmijenila sve globalne varijable koje nam trebaju ("donja_granica", "gornja_granica" i "sredina_niza"), ali zato imamo njihove stare vrijednosti na stogovima.
   gornja_granica:=stog_s_gornjim_granicama[vrh_stoga]
   sredina_niza:=stog_sa_sredinama_niza[vrh_stoga]
   donja_granica:=sredina_niza
   AsmStart
       call hybrid_sort
   AsmEnd
   donja_granica:=stog_s_donjim_granicama[vrh_stoga]
   gornja_granica:=stog_s_gornjim_granicama[vrh_stoga]
   sredina_niza:=stog_sa_sredinama_niza[vrh_stoga]
   ;Spajanje nizova originalni_niz[donja_granica..sredina_niza] i originalni_niz[sredina_niza..gornja_granica] u jedan niz...
   i:=donja_granica
   gdje_smo_u_prvom_nizu:=donja_granica
   gdje_smo_u_drugom_nizu:=sredina_niza
   While i<gornja_granica
       If (gdje_smo_u_prvom_nizu=sredina_niza | originalni_niz[gdje_smo_u_drugom_nizu]<originalni_niz[gdje_smo_u_prvom_nizu]) & gdje_smo_u_drugom_nizu<gornja_granica
           pomocni_niz[i]:=originalni_niz[gdje_smo_u_drugom_nizu]
           gdje_smo_u_drugom_nizu:=gdje_smo_u_drugom_nizu+1
       Else
           pomocni_niz[i]:=originalni_niz[gdje_smo_u_prvom_nizu]
           gdje_smo_u_prvom_nizu:=gdje_smo_u_prvom_nizu+1
       EndIf
       i:=i+1
   EndWhile
   i:=donja_granica
   While i<gornja_granica
       originalni_niz[i]:=pomocni_niz[i]
       i:=i+1
   EndWhile
   vrh_stoga:=vrh_stoga-1 ;Oslobodi mjesto na stogovima.
   AsmStart
       ret
   AsmEnd
Else ;QuickSort algoritam (nasumicno ispremjestani podnizovi)...
   broj_pokretanja_QuickSorta := broj_pokretanja_QuickSorta + 1
   ;Daljnji kod je priblizno prepisan s https://www.geeksforgeeks.org/quick-sort/
   pivot := originalni_niz[gornja_granica - 1]
   i := donja_granica - 1
   j := donja_granica
   While j < gornja_granica - 1
       If originalni_niz[j] < pivot
           i := i + 1
           pomocna_varijabla_za_zamijenu := originalni_niz[i]
           originalni_niz[i] := originalni_niz [j]
           originalni_niz[j] := pomocna_varijabla_za_zamijenu
       EndIf
       j:=j+1
   EndWhile
   pomocna_varijabla_za_zamijenu := originalni_niz[i + 1]
   originalni_niz[i + 1] := originalni_niz[gornja_granica - 1]
   originalni_niz[gornja_granica - 1] := pomocna_varijabla_za_zamijenu
   gdje_je_pivot := i + 1
   vrh_stoga := vrh_stoga + 1 ;Zauzmi mjesta na stogu za rekurziju (ne koristimo sistemski stog, kao sto koristi C++, nego koristimo vise globalnih polja kao stogove).
   stog_s_donjim_granicama[vrh_stoga] := donja_granica
   stog_s_gornjim_granicama[vrh_stoga] := gornja_granica
   stog_sa_sredinama_niza[vrh_stoga] := gdje_je_pivot
   gornja_granica := gdje_je_pivot
   AsmStart
       call hybrid_sort
   AsmEnd
   donja_granica := stog_s_donjim_granicama[vrh_stoga]
   gornja_granica := stog_s_gornjim_granicama[vrh_stoga]
   gdje_je_pivot := stog_sa_sredinama_niza[vrh_stoga]
   donja_granica := gdje_je_pivot
   AsmStart
       call hybrid_sort
   AsmEnd
   vrh_stoga := vrh_stoga - 1 ;Oslobodi mjesto na stogovima.
   AsmStart
       ret
   AsmEnd
EndIf
AsmStart ;Ovdje tok programa ne smije doci. Ako dode, pozovi debugger.
   call abort
AsmEnd
This time, I didn't make an executable program using FlatAssembler, but a static library that can be compiled using GNU Assembler and linked with, for instance, a C++ program that will test it. So, I can get more precise measurements of its performance. Now it works better than last time for nearly-sorted arrays (it's as fast as C++ "sort" directive), but it's around 50 times slower than C++ "sort" is if the array is randomly shuffled, and around 2 times slower than my last program was. Oddly, I thought I implemented QuickSort(running when the sortedness is near 0) much more efficiently now.
[Image: test_results.png]
Implementing it as a static linking library rather than as an executable also makes it easier to see what's going on inside:
[Image: which_algorithms_are_used.png]
There also appears to be some surge in the number of QuickSorts executed when the sortedness is around 0.9 (when MergeSort will almost certainly do a better job), I can't figure out exactly why (yet alone that there is an easy fix).
Reply



Messages In This Thread
C++ "sort" - by FlatAssembler - November 13, 2019 at 12:14 pm
RE: C++ "sort" - by FlatAssembler - December 12, 2019 at 4:51 am
RE: C++ "sort" - by Abaddon_ire - December 12, 2019 at 9:48 am
RE: C++ "sort" - by FlatAssembler - December 12, 2019 at 11:21 am
RE: C++ "sort" - by FlatAssembler - December 12, 2019 at 2:42 pm
RE: C++ "sort" - by FlatAssembler - December 13, 2019 at 2:50 pm
RE: C++ "sort" - by Fake Messiah - December 13, 2019 at 4:45 pm
RE: C++ "sort" - by FlatAssembler - December 14, 2019 at 5:06 am
RE: C++ "sort" - by Abaddon_ire - December 14, 2019 at 10:29 pm
RE: C++ "sort" - by FlatAssembler - December 15, 2019 at 3:55 am
RE: C++ "sort" - by Abaddon_ire - December 15, 2019 at 10:13 am
RE: C++ "sort" - by FlatAssembler - December 15, 2019 at 1:41 pm
RE: C++ "sort" - by Abaddon_ire - December 15, 2019 at 3:33 pm
RE: C++ "sort" - by FlatAssembler - December 17, 2019 at 1:31 am
RE: C++ "sort" - by FlatAssembler - December 19, 2019 at 7:54 am
RE: C++ "sort" - by mordant - December 20, 2019 at 2:19 pm
RE: C++ "sort" - by FlatAssembler - December 23, 2019 at 8:45 am
RE: C++ "sort" - by FlatAssembler - December 29, 2019 at 9:21 am
RE: C++ "sort" - by SteelCurtain - December 29, 2019 at 10:27 am
RE: C++ "sort" - by Abaddon_ire - December 29, 2019 at 11:35 am
RE: C++ "sort" - by SteelCurtain - December 29, 2019 at 3:26 pm
RE: C++ "sort" - by Abaddon_ire - July 4, 2020 at 2:15 pm
RE: C++ "sort" - by FlatAssembler - July 6, 2020 at 10:57 am
RE: C++ "sort" - by Abaddon_ire - July 6, 2020 at 4:37 pm
RE: C++ "sort" - by FlatAssembler - July 9, 2020 at 4:07 am
RE: C++ "sort" - by FlatAssembler - December 30, 2019 at 11:47 am
RE: C++ "sort" - by FlatAssembler - January 2, 2020 at 4:47 am
RE: C++ "sort" - by FlatAssembler - January 5, 2020 at 12:06 pm
RE: C++ "sort" - by FlatAssembler - January 10, 2020 at 2:59 pm
RE: C++ "sort" - by SteelCurtain - January 10, 2020 at 10:03 pm
RE: C++ "sort" - by FlatAssembler - January 21, 2020 at 1:51 am
RE: C++ "sort" - by FlatAssembler - July 4, 2020 at 7:57 am
RE: C++ "sort" - by Brian37 - July 6, 2020 at 11:32 am
RE: C++ "sort" - by BrianSoddingBoru4 - July 6, 2020 at 5:26 pm
RE: C++ "sort" - by FlatAssembler - August 29, 2020 at 8:03 am



Users browsing this thread: 1 Guest(s)