HiveBrain v1.2.0
Get Started
← Back to all entries
snippetjavaMinor

Memory/performance of merge sort code

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
mergeperformancememorycodesort

Problem

I wrote up merge sort code for some late night snack. I have gotten it working, but was just looking learn if I was missing anything in terms of efficiency. Could this code be significantly improved in terms of efficiency (space/time/unnecessary checks)?

```
package com.komal.sort;
import java.util.Arrays;
import java.util.Date;

public class MergeSort {

static int a[]= {1,2,7,4,5,8,12,54,23,66,22,312,65,23,65,867,222,21,1000};

public static void main(String[] args) {

System.out.println(new Date());
System.out.println("input length: "+ a.length);
int [] result =new MergeSort().mergeSort("start", a);
System.out.println("Result: "+Arrays.toString(result));
System.out.println("\nResult array size: "+ result.length);
System.out.println("\n"+new Date());

}

public int[] mergeSort( String subTree, int [] a)
{
System.out.println("MergeSort.mergeSort():"+subTree+" inputs:"+ Arrays.toString(a));
if(a.length>1)
{
int[] leftArray= Arrays.copyOfRange(a, 0, (a.length/2));
int[] rightArray= Arrays.copyOfRange(a, (a.length/2), a.length);
return merge(mergeSort("left", leftArray), mergeSort("right",rightArray));
}
return a;
}

public int[] merge(int[] leftArray, int[] rightArray)
{

int[] input = new int[leftArray.length+ rightArray.length];
int left=0;
int i=0;
int right=0;
while(left+right!= leftArray.length + rightArray.length)
{
if(left>=leftArray.length ){
input[i]= rightArray[right];
i++;
right++;
}
else if(right>=rightArray.length ){
input[i]= leftArray[left];
i++;
left++;
}
else{

if(leftArray[left]<rightArray[right])

Solution

Unnecessary array creation

The mergeSort method creates leftArray and rightArray, but it doesn't really need to.
merge could use a single input array with start, middle and end indexes.
The reduced array creation will optimize the performance,
though it will not change the order of complexity.

Inefficient merging

The conditions throughout the merge step are not organized efficiently.

First of all, for each target element, this condition is evaluated:

left + right != leftArray.length + rightArray.length


Instead of using leftArray.length + rightArray.length, you could use the target length that is already known without addition.
But in any case, this condition is not very expressive,
it just reveals that we haven't reached the end of one of the arrays,
and inside the loop body we still need to check again if reached the end of one of them.

A more efficient and clearer way to organize the conditions is to use 3 loops:

while (left < leftArray.length && right < rightArray.length) {
        if (leftArray[left] < rightArray[right]) {
            input[i++] = leftArray[left++];
        } else {
            input[i++] = rightArray[right++];
        }
    }
    while (left < leftArray.length) {
        input[i++] = leftArray[left++];
    }
    while (right < rightArray.length) {
        input[i++] = rightArray[right++];
    }


Naming

input is not a good name for an array that in fact stores the output of a method.

Code Snippets

left + right != leftArray.length + rightArray.length
while (left < leftArray.length && right < rightArray.length) {
        if (leftArray[left] < rightArray[right]) {
            input[i++] = leftArray[left++];
        } else {
            input[i++] = rightArray[right++];
        }
    }
    while (left < leftArray.length) {
        input[i++] = leftArray[left++];
    }
    while (right < rightArray.length) {
        input[i++] = rightArray[right++];
    }

Context

StackExchange Code Review Q#131128, answer score: 5

Revisions (0)

No revisions yet.