Я пишу небольшой набор тестов для тестирования производительности 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.