Быстрая сортировка быстрее в Java, чем в C ++ - PullRequest
0 голосов
/ 26 сентября 2019

Я работаю над проектом, в котором я сравниваю java и c ++, используя quickSort.Я не могу понять, почему, но Java, как правило, в два раза быстрее, чем с ++.Я думаю, что это может быть связано с оптимизацией компилятора, но я пробовал c ++ в Visual Studio и G ++, но я все еще получаю аналогичные результаты.Возможно, я не оптимизировал алгоритм, но хотел, чтобы алгоритмы были максимально похожими.Я думал о реализации векторов вместо массивов для c ++, но я не был уверен, повлияет ли это на эталонный тест.

Редактирование с использованием g ++ -O3 и 64-битной OpenJDK v11.0.4 в качестве компиляторов.Я пытался запустить его на нескольких разных компьютерах, и независимо от аппаратного обеспечения Java по-прежнему превосходит C ++.

import java.io.*;
import java.util.*;
import java.text.DecimalFormat;
import java.util.concurrent.TimeUnit;

public class quickSortBench {

    public static void main(String[] args) {
        int[] arr = new int[10000000];
        int[] warmupArr = new int[5000000];
        long[] starting = new long[500];
        long[] ending = new long[500];
        long[] timeDif = new long[500];
        DecimalFormat fmt = new DecimalFormat("#");
        Random rand = new Random();


        //WARMUP//
        for (double j = 1; j <= 100; j++) {
          for (int k = 0; k < warmupArr.length; k++) {
            warmupArr[k] = rand.nextInt();
          }
          double perc = (j / 100) * 100;
          System.out.print("Warming Up: " + fmt.format(perc) + "%\r");

          quickSort(warmupArr, 0, warmupArr.length-1);
        }
        //END WARMUP//

        //BENCHMARK//
        double j = 1;
        for (int l = 0; l < timeDif.length; l++) {
          double perc = ((j + 1) / 500) * 100;
          System.out.print("Benchmarking. . . This may take a few minutes: " + fmt.format(perc) + "%\r");
          for (int m = 0; m < arr.length; m++) {
            arr[m] = rand.nextInt();
          }

          long startTime = System.currentTimeMillis();
          quickSort(arr, 0, arr.length-1);
          long endTime = System.currentTimeMillis();

          starting[l] = startTime;
          ending[l] = endTime;
          timeDif[l] = endTime - startTime;
          j++;
        }
        //END BENCHMARK//

    public static void quickSort(int[] arr, int start, int end){
        int partition = partition(arr, start, end);

        if(partition-1>start) {
            quickSort(arr, start, partition - 1);
        }
        if(partition+1<end) {
            quickSort(arr, partition + 1, end);
        }
    }

    public static int partition(int[] arr, int start, int end){
        int pivot = arr[end];

        for(int i=start; i<end; i++){
            if(arr[i]<pivot){
                int temp= arr[start];
                arr[start]=arr[i];
                arr[i]=temp;
                start++;
            }
        }

        int temp = arr[start];
        arr[start] = pivot;
        arr[end] = temp;

        return start;
    }
}

#include <iostream>
#include <fstream>
#include <ctime>
#include <cmath>
#include <chrono>

using namespace std::chrono;

void quickSort(int arr[], int start, int end);
int part(int arr[], int start, int end);

int main() {
    int arrLength = 10000000;
    int warmupLength = 5000000;
    int timeDifLength = 500;
    auto* starting = new int[timeDifLength];
    auto* ending = new int[timeDifLength];
    auto* timeDif = new int[timeDifLength];
    std::ofstream data;

    //WARMUP//
    for (double i = 0; i < 100; i++) {
        int* warmupArr = new int[warmupLength];
        for (int j = 0; j < warmupLength; j++) {
            warmupArr[j] = rand();
        }
        double perc = (i / 100) * 100;
        std::cout << "Warming Up: " << round(perc) << "%\r";
        quickSort(warmupArr, 0, warmupLength - 1);
        delete[] warmupArr;
    }
    //END WARMUP//

    //BENCHMARK//
    double j = 1;
    for (int l = 0; l < timeDifLength; l++) {
        int* arr = new int[arrLength];
        double perc = ((j + 1) / 500) * 100;
        std::cout << "Benchmarking. . . This may take a few up to 15 minutes: " << round(perc) << "%\r";
        for (int m = 0; m < arrLength; m++) {
            arr[m] = rand();
        }

        auto startTime = high_resolution_clock::now();
        quickSort(arr, 0, arrLength - 1);
        auto endTime = high_resolution_clock::now();

        delete[] arr;

        starting[l] = duration_cast<milliseconds>(startTime.time_since_epoch()).count();
        ending[l] = duration_cast<milliseconds>(endTime.time_since_epoch()).count();
        timeDif[l] = duration_cast<milliseconds>(endTime - startTime).count();
        j++;
    }

    delete[] starting;
    delete[] ending;
    delete[] timeDif;
}

void quickSort(int arr[], int start, int end) {
    int partition = part(arr, start, end);

    if (partition - 1 > start) {
        quickSort(arr, start, partition - 1);
    }
    if (partition + 1 < end) {
        quickSort(arr, partition + 1, end);
    }
}

int part(int arr[], int start, int end) {
    int pivot = arr[end];

    for (int i = start; i < end; i++) {
        if (arr[i] < pivot) {
            int temp = arr[start];
            arr[start] = arr[i];
            arr[i] = temp;
            start++;
        }
    }

    int temp = arr[start];
    arr[start] = pivot;
    arr[end] = temp;

    return start;
}
...