Язык D: использование динамического массива с кортежами и отладкой «Программа завершена с кодом -11» - PullRequest
0 голосов
/ 21 октября 2019

Я пишу небольшой набор тестов для тестирования производительности Tuples vs Structs в D.

Это мой код:

//---------------------
// Imports
//---------------------

import std.algorithm;
import std.array;
import std.container;
import std.conv;
import std.datetime.stopwatch;
import std.functional;
import std.range;
import std.stdio;
import std.string;
import std.typecons;

import containers.dynamicarray;

//---------------------
// Global
//---------------------

struct recStruct {
    int i;
    string s;
}
alias Tuple!(int,"i", string,"s") recTuple;

DynamicArray!recStruct arr1;
DynamicArray!recTuple arr2;

void preRun() {

}

//---------------------
// Test functions
//---------------------

void func1() {

    for (int i=0; i<100; i++) {
        arr1 ~= recStruct(i,"done");
    }
    for (int i=0; i<100; i++) {
        auto k = arr1[i].i;
        auto z = arr1[i].s;
    }
}

void func2() {
    for (int i=0; i<100; i++) {
        arr2 ~= recTuple(i,"done");
    }
    for (int i=0; i<100; i++) {
        auto k = arr2[i].i;
        auto z = arr2[i].s;
    }
}   

void func3() {


}

void func4() {


}

//---------------------
// Main
//---------------------

void main(string[] args)
{
    writeln(args);
    uint times = to!uint(args[1]);

    writeln("==================================");
    writeln(" Running tests: x" ~ args[1]);
    writeln("==================================\n");

    auto result = benchmark!(func1, func2, func3, func4)(times);

    preRun();

    writeln("func1 : " ~ to!string(cast(Duration)result[0]));
    writeln("func2 : " ~ to!string(cast(Duration)result[1]));
    writeln("func3 : " ~ to!string(cast(Duration)result[2]));
    writeln("func4 : " ~ to!string(cast(Duration)result[3]));

    writeln("\nAll tests completed.");
}

Однако, func2 (тот, который использует кортежи), кажется, вызывает сбой (при использовании тестового коэффициента 500k + - то есть, когда он выполняется такое количество раз). Когда я запускаю его через lldb, он дает мне это (похоже на что-то, связанное с GC?):

Process 27170 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x103600000)
    frame #0: 0x000000010002f786 test`_D2gc4impl12conservativeQw3Gcx12collectRootsMFNbNlPvQcZv + 66
test`_D2gc4impl12conservativeQw3Gcx12collectRootsMFNbNlPvQcZv:
->  0x10002f786 <+66>: movq   (%rbx), %r13
    0x10002f789 <+69>: movq   %r13, %rcx
    0x10002f78c <+72>: subq   %r14, %rcx
    0x10002f78f <+75>: cmpq   %r15, %rcx
Target 0: (test) stopped.

Есть идеи, что происходит и как я могу это исправить?

(В случае, если это имеет значение, компилятор является LDC на macOS)


ОБНОВЛЕНИЕ: Замена DynamicArray на простой массив или std.container.Array, только для основанного на TupleВо-первых, кажется, что проблема исчезнет ... Хотя я определенно предпочитаю Динамические для производительности. Хмм ...


ОБНОВЛЕНИЕ:

Разница в производительности для времен = 300000

==================================
 Running tests: x300000
==================================

func1 : 2 secs, 36 ms, and 526 μs
func2 : 1 sec, 637 ms, and 692 μs
func3 : 557 μs and 8 hnsecs
func4 : 554 μs and 5 hnsecs

All tests completed.
...