Результаты тестов двоичного дерева - PullRequest
0 голосов
/ 19 сентября 2018

Я наткнулся на веб-сайт, делающий бенчмарки .В этом случае Golang против C ++, бинарные деревья.

Решение C ++ делает ОГРОМНО лучше, чем golang, используя выделение пула памяти.Я могу отстать от этого, но удивляюсь, как реализация без этого обойдется.Поэтому я изменил его так, чтобы он больше походил на код Голанга, и удалил параллелизм для обоих.

В этом примере и на моей машине код голанга выполняется примерно за 24 секунды.Код C ++ занимает в среднем 126 секунд.Я не ожидал этого результата вообще.Я ожидал, что C ++ все еще будет быстрее или, возможно, немного медленнее, но не в 5 раз.

Я совершил какую-то огромную ошибку?Или вы знаете причину этого?Код для обеих программ приведен ниже:

Построен с:

mingw32-g ++. Exe -Wall -fexceptions -O2 -c D: \ TMP \ Test \ main.cpp -oobj \ Release \ main.o mingw32-g ++. exe -o bin \ Release \ Test.exe obj \ Release \ main.o -s

#include <iostream>

using namespace std;

class Node {
public:
    Node(uint64_t d);
    ~Node();
    int Check();
private:
    Node* l;
    Node* r;
};

Node::Node(uint64_t d){
    if (d > 0){
        l = new Node(d - 1);
        r = new Node(d - 1);
    } else {
        l = 0;
        r = 0;
    }
}

Node::~Node(){
    if(l){
        delete l;
        delete r;
    }
}

int Node::Check(){
    if (l) {
        return l->Check() + 1 + r->Check();
    } else {
        return 1;
    }
}

int main()
{
    uint64_t min_depth = 4;
    uint64_t max_depth = 21;
    for (uint64_t d = min_depth; d <= max_depth; d += 2) {
        uint64_t iterations = 1 << (max_depth - d + min_depth);
        uint64_t c = 0;
        for (uint64_t i = 1; i < iterations; i++) {
            Node* a = new Node(d);
            c += a->Check();
            delete a; // I tried commenting this line but it made no big impact
        }
        cout << iterations << " trees of depth " << d << " check: " << c << "\n";
    }
    return 0;
}

Голанг:

go версия go1.7.1 windows / amd64

package main

import(
    "fmt"
)

type Node struct {
    l *Node
    r *Node
}

func (n *Node) check() int {
    if n.l != nil {
        return n.l.check() + 1 + n.r.check()
    } else {
        return 1
    }
}

func make(d uint) *Node {
    root := new(Node)
    if d > 0 {
        root.l = make(d-1)
        root.r = make(d-1)
    }
    return root
}

func main(){
    min_depth := uint(4)
    max_depth := uint(21)
    for d := min_depth; d <= max_depth; d += 2 {
        iterations := 1 << (max_depth - d + min_depth)
        c := 0
        for i := 1; i < iterations; i++ {
            a := make(d)
            c += a.check()
        }
        fmt.Println(iterations, " trees of depth ", d, " check: ", c)
    }
}

1 Ответ

0 голосов
/ 07 марта 2019

Это что-то с вашим компьютером, на котором вы работали, потому что я получаю ожидаемый результат, когда C ++ в два раза быстрее, чем ход.

C ++

time cmake-build-debug/main
2097152 trees of depth 4 check: 65011681
524288 trees of depth 6 check: 66584449
131072 trees of depth 8 check: 66977281
32768 trees of depth 10 check: 67074049
8192 trees of depth 12 check: 67092481
2048 trees of depth 14 check: 67074049
512 trees of depth 16 check: 66977281
128 trees of depth 18 check: 66584449
32 trees of depth 20 check: 65011681
cmake-build-debug/main  21.09s user 0.02s system 99% cpu 21.113 total

GO

 jonny@skyhawk  ~/Projects/benchmark  time ./main            ✔  2604  02:34:29 
2097152  trees of depth  4  check:  65011681
524288  trees of depth  6  check:  66584449
131072  trees of depth  8  check:  66977281
32768  trees of depth  10  check:  67074049
8192  trees of depth  12  check:  67092481
2048  trees of depth  14  check:  67074049
512  trees of depth  16  check:  66977281
128  trees of depth  18  check:  66584449
32  trees of depth  20  check:  65011681
./main  48.72s user 0.52s system 197% cpu 24.905 total

Я собрал main.cpp C ++ с основными / стандартными настройками CLion (этот CMakeLists.txt, который создаст main.cpp)

cmake_minimum_required(VERSION 3.3)
project(test_build)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")

set(BUILD_1 main)
set(SOURCE_FILES_1 main.cpp)
add_executable(${BUILD_1} ${SOURCE_FILES_1})
...