I have coded an assembler QuickSort and found that is it slower than the array.sort in java. I am wondering if anyone would know of why I cannot match the speed of some of the higher level languages (I am assuming C would probably be quicker also)
I have tested with 1,000,000 * 1024 bytes. I get approx 2 seconds to complete the sort while Array.Sort in Java will do it in about .8 second
I don't think there is any problem in actually moving the data as I have independently tested that and it moves quite quickly.
    %macro $copyBytes 3
        mov RSI,%1                                  ; Grab the Src Address
        mov RDI,%2                                  ; Grab the Dst Address
        mov rcx,%3                                  ; Grab the length
    %%l:movsb                                       ; Move the data
        loop %%l    
    %endmacro
    %imacro $getAddress 2
        mov %1,r_Table                              ; Start of Table to RSI/RDI
        mov rax,%2                                  ; Lower/Upper to RAX
        mul r_recordLength                          ; Multiply by Record Length
        add %1,rax                                  ; add offset to RSI/RDI
    %endmacro
    %define r_recordLength  r8
    %define r_startPos      r10             
    %define r_noOfBytes     r11
    %define r_Ubound        r15
    %define @left           r10
    %define @right          r11
    %define @pivotValue     r12
    %define @prevLeft       r13
    [section .bss]
        d_startPos          resq 1
        d_noOfBytes         resq 1      
        pivotValue          resb 128                ; This gives tha max sortkey size
        LeftAddress         resq 1
        RightAddress        resq 1
    [section .text] 
;   Call the recursive SORT
    push 0                                          ; Push the 1st Left
    push r_Ubound                                   ; Push the 1st Right
    Call _QSort
    pop rax
    pop rax
;-----------------------------------------------------------------------
;   Recursive Sort
;-----------------------------------------------------------------------
_QSort:
    mov @left,qword[rsp+16]                         ; get the Left Index
    mov @right,qword[rsp+8]                         ; get the Right Index
;   if  left >= right                   ; Exit when Left is not < Right
    cmp @left,@right
        jnl .Exit
;   pivotValue = RandomNo[ [ left + right / 2 ] ] CALCULATE pivotValue
    mov rax,@left                                   ; Grab the left
    add rax,@right                                  ; add the right
    shr rax,1                                       ; and divide by 2
    $getAddress RSI,rax                          ; get the address of this slot
    $copyBytes RSI,pivotValue,qword[d_noOfBytes]     ; and copy it to pivotValue
;   prevLeftIdx = [moveThem]
    push @left                                      ; preserve the Left index
    push @right                                     ; preserve the Right index
    call _moveThem                                  ; do the moves
    pop @right                                      ; restore the Right index
    pop @left                                       ; restore the Left index                                                        
    mov @prevLeft,rax                               ; and save the returned value
;   -------------------------------------
;   Recursive Call - (left, prevLeft - 1)
;   -------------------------------------
    push @left                                      ; preserve the Left index
    push @right                                     ; preserve the Right index
    push @left                                      ; push the 1st parameter (Left)
    mov rax,@prevLeft                               ; get the previous left
    dec rax                                         ; minus 1
    push rax                                        ; push the 2nd parameter
    Call _QSort                                     ; Call yourself     
    pop rax                                         ; Junk this
    pop rax                                         ; Junk this
    pop @right                                      ; restore the Right index
    pop @left                                       ; restore the Left index
;   ----------------------------------
;   Recursive Call - (prevLeft, right)  
;   ----------------------------------
    push @left                                      ; preserve the Left index
    push @right                                     ; preserve the Right index
    push @prevLeft                                  ; push the 1st parameter (previous left
    push @right                                     ; push the 2nd parameter (Right0
    Call _QSort                                     ; Call yourself
    pop rax                                         ; Junk this
    pop rax                                         ; Junk this
    pop @right                                      ; restore the Right index
    pop @left                                       ; restore the Left index
    .Exit:
_QSort_EXIT:
    ret
_moveThem:
;   repeat.while (left <= right)
    cmp @left,@right                                ; Compare Left to Right Index
        jg .Exit                                    ; exit if Left is > Right
;   repeat.while (Key[left] < pivotValue)
;           left    = left + 1
;   end.repeat
    .start1:$getAddress RSI,@left                    ; Get the Start of the record 
            add RSI,qword[d_startPos]               ; add the requested starting position
            mov qword[LeftAddress],RSI              ; and save it
            mov RDI,pivotValue                      ; Get the start of the pivotValue
            mov rcx,qword[d_noOfBytes]              ; Grab the length (LOOP Ctr)
            cld                                     ; Clear the direction flag - left to right
    repe    cmpsb                                   ; Compare the String
            jnl .cont1                              ; If result not < than exit While Loop                                          
            inc @left                               ; get the next table slot
            jmp .start1                             ; and repeat
    .cont1:
    cmp @left,@right                                ; Compare Left to Right Index
        jg .Exit                                    ; exit if Left is > Right
;   repeat.while (Key[right]> pivotValue)
;       right   = right - 1
;   end.repeat
    .start2:$getAddress RSI,@right                   ; Get the Start of the record 
            add RSI,qword[d_startPos]               ; add the requested starting position
            mov qword[RightAddress],RSI             ; and save it
            mov RDI,pivotValue                      ; Get the start of the pivotValue 
            mov rcx,qword[d_noOfBytes]              ; Grab the length (LOOP Ctr)
            cld                                     ; Clear the direction flag - left to right
    repe    cmpsb                                   ; Compare the string    
            jng .cont2                              ; If result not > than exit While Loop  
            dec @right                              ; get the previous table slot
            jmp .start2                             ; and repeat
    .cont2:
    cmp @left,@right                                ; Compare Left to Right Index
        jg .Exit                                    ; exit if Left is > Right
        jl .DoTheMove                               ; Do the move if less than
    ;   No need to do the move if left = right
        inc @left                                   ; increment the left 
        jmp .Exit                                   ; and head for the exit
;   if left <= right - SWAP left and right data
.DoTheMove:
    mov RSI,qword[LeftAddress]                      ; grab the Left address
    mov RDI,qword[RightAddress]                     ; grab the Right address        
    mov rcx,r_recordLength                          ; and grab the record length
    .start3:cmp rcx,8                               ; Have we still got 8 bytes to move
                jb .start4                          ; If not go and pick up the last few bytes
            mov rax,qword[RSI]                      ; grab the left 8 bytes                                     
            mov rbx,qword[RDI]                      ; grab the right 8 bytes
            xchg rax,rbx                            ; swap them over
            mov qword[RSI],rax                      ; put the right 8 bytes to the left
            mov qword[RDI],rbx                      ; put the left 8 bytes to the right 
            add RSI,8                               ; setup RSI for the next 8 bytes
            add RDI,8                               ; setup RDI for the next 8 bytes                                                    
            sub rcx,8                               ; take 8 away from the counter
            jmp .start3                             ; and loop around
    .start4:cmp rcx,0                               ; Have we still got anything to move
                jna .cont4                          ; If not we are done            
            mov ah,byte[RSI]                        ; grab the left byte                                            
            mov al,byte[RDI]                        ; grab the right byte
            xchg ah,al                              ; swap them over
            mov byte[RSI],ah                        ; put the right byte to the left
            mov byte[RDI],al                        ; put the left byte to the right
            add RSI,1                               ; setup RSI for the next byte
            add RDI,1                               ; setup RDI for the next bytes
            sub rcx,1                               ; take 1 away from the counter
            jmp .start4                             ; and loop around
    .cont4:
    inc @left                                       ; Next Left
    dec @right                                      ; Previous Right
    jmp _moveThem                                   ; Back to the Start
.Exit:  
    mov rax,@left                                   ; Return the Left value
_moveThem_EXIT:
    ret
import java.util.Arrays;
class QuickSort {
    public static void Sort(String[] strArray, int lowerIndex, int higherIndex) 
    {        
        int left = lowerIndex;
        int right= higherIndex;
        int x;
        String pivot, temp;
        pivot = strArray[lowerIndex+(higherIndex-lowerIndex)/2];
        while (left <= right) {
          x = strArray[left].compareTo(pivot);
          while (x < 0) {
            left++;  
            x = strArray[left].compareTo(pivot);
          }
          x = strArray[right].compareTo(pivot);
          while (x > 0) {
            right--;
            x = strArray[right].compareTo(pivot);
          }
          if (left <= right) {
            temp = strArray[left];
            strArray[left] = strArray[right];
            strArray[left] = temp;
            left++;
            right--;
          }
        }
        if (lowerIndex < right)
            Sort(strArray,lowerIndex,right);
        if (left < higherIndex)
            Sort(strArray,left,higherIndex);
    }
}
public class V2_11 {
  public static void main(String[] args) {
    String strArray[] = new String[1000001];       
    String letters[] = {"a","b","c","d","e","f","g","h","i","j",
                        "k","l","m","n","o","p","q","r","s","t",
                        "u","v","w","x","y","z"};
    String word;
    String spaces[] = new String[998];
    int random;
  //---------------
  //Build the Array
  //---------------
    System.out.println("Filling Array");  
    System.out.println(java.time.LocalTime.now());  
    for (int i=0;i < 1000000;i++){ 
      word="";
      for (int j=0;j< 26;j++){ 
        random = (int)(Math.random() * 9 + 0);
        word=word+letters[random];
      }
      strArray[i]=word+spaces;
    }   
    System.out.println(java.time.LocalTime.now());
  //--------------
  //Sort the Array
  //--------------
    System.out.println("Sorting");  
    System.out.println(java.time.LocalTime.now());    
  //---Arrays.sort(strArray);
    QuickSort.Sort(strArray,0, 999999);   
    System.out.println(java.time.LocalTime.now());
  //-------------------
  //Display some Reults
  //-------------------
    for (int i=100;i< 110;i++)
    { 
      System.out.println(strArray[i]);
    }
  }
}
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>
#include <stdlib.h>
    struct timeval start, stop;
    double secs = 0;
    char strArray[1000000][27];
    char pivotValue[27]; 
    char temp[27]; 
    int prevLeftIdx;
int moveThem(int left, int right)
{   int x;
    while (left <= right) {
       x = strcmp(strArray[left],pivotValue);
       while (x < 0) {
         left++;  
            x = strcmp(strArray[left],pivotValue);
       }
       x = strcmp(strArray[right],pivotValue);
       while (x > 0) {
         right--;
         x = strcmp(strArray[right],pivotValue);
       }
       if (left <= right) {
         strcpy(temp,strArray[left]);
         strcpy(strArray[left],strArray[right]);
         strcpy(strArray[right],temp);
         left++;
         right--;
       }
    }
    return left;
}
int QuickSort(int left, int right) 
{
    if (left>=right)
        {return 0;}
    strcpy(pivotValue, strArray[(left+right)/2]);
    prevLeftIdx=moveThem(left,right);
    QuickSort(left,prevLeftIdx-1);
    QuickSort(prevLeftIdx,right);      
}
int main()
{
    char letters[26] = "abcdefghijklmnopqrstuvwxyz";
    char c_Null[1] = "\0";
    char word[27];
    int i,j,random;
  //---------------
  //Build the Array
  //---------------
    puts("Filling Array"); 
    gettimeofday(&start, NULL);
    srand(time(NULL));
    for (i=0;i < 1000000;i++){ 
      for (j=0;j< 26;j++){ 
        random = rand() % 24;
        word[j] = letters[random];
      }
      word[j] = *c_Null;
      strcpy(strArray[i],word);
    }   
    gettimeofday(&stop, NULL);
    secs = (double)(stop.tv_usec - start.tv_usec) / 1000000 + (double)(stop.tv_sec - start.tv_sec);
    printf("time taken %f\n",secs);
  //--------------
  //Sort the Array
  //--------------
    puts("Sorting"); 
    gettimeofday(&start, NULL);   
    QuickSort(0, 999999);   
    gettimeofday(&stop, NULL);
    secs = (double)(stop.tv_usec - start.tv_usec) / 1000000 + (double)(stop.tv_sec - start.tv_sec);
    printf("time taken %f\n",secs);
  //-------------------
  //Display some Reults
  //-------------------
   for (i=0;i<10 ;i++)
   { 
     puts(strArray[i]); 
   }
}
RESULTS FOR C program
Filling Array
time taken 0.245878
Sorting
time taken 0.473481
aaaagajqpbutmaxxhgjkauwmwg
aaaakestelpvsrgiemafwtujev
aaaamnvrdueegvfilkvsabdomd
aaaapspaurwurvecikmjibkwfk
aaaauclobckwflwushhnhiafws
aaabaiueabmqlumijuhlrvmgtf
aaabcqehhoeegkhpeondnbsqjb
aaabmwxdrcpfxlhbmggxvjcaoc
aaabplwowigaxmpjipqxkntilc
aaacjsuqkmbwnglltqsspvvtlr
