2014-09-01 2 views
2

У меня есть простой массив:Как ускорить копирование общего массива?

Myarray<T> = array[0..100] of T; 

Как скопировать этот так быстро, как это возможно, в другой массив. Обратите внимание, что источником всегда является простой общий массив, а dest может быть динамическим массивом. (но я сомневаюсь, что это важно).

Я попытался

move(Source[0], dest[0], count * sizeof(T)); 

Но это не играет хорошо с управляемыми типами.

Я в надежде получить что-то быстрее, чем:

for i:= 0 to count -1 do D[i]:= S[i]; 

Какие варианты у меня есть?

фона
Массива является частью структуры ВТКЕЯ и есть много копирования происходит.
Мне нужна скорость.

+0

Почему вы надеетесь, что простое назначение может быть улучшено? В чем проблема простого назначения? –

+0

Не так быстро, как ходы. Мне хотелось бы что-то посредине. – Johan

+0

Но ходы не работают. Задание выполняется. Каким образом это неэффективно? Думаю, этот вопрос будет путать из-за всего кода. Вам просто нужен более эффективный способ назначения. Я думаю, вы должны задать этот общий вопрос, а не представить весь другой код, который нам не нужно видеть. Корень вашего Q - это перфорация задания. Пожалуйста, не могли бы вы спросить об этом. Многие из ваших вопросов подобны этому, когда вы представляете множество посторонних деталей, которые скрывают суть вопроса. –

ответ

2

я задал тот же вопрос, на Google+ - https://plus.google.com/u/0/116430453567926016001/posts/b1u1shzkmrW

код является Стефан Glienke и я повторно отправил код здесь с незначительными изменениями двух типов переменных, так что 64 бит, совместимая.

uses 
    TypInfo, 
    SysUtils; 

type 
    TArray = record 
    class function Clone<T>(const source: T): T; static; 
    end; 

function DynArrayLength(const A: Pointer): NativeInt; 
type 
    PDynArrayRec = ^TDynArrayRec; 
    TDynArrayRec = packed record 
    {$IFDEF CPUX64} 
    _Padding: LongInt; 
    {$ENDIF} 
    RefCnt: LongInt; 
    Length: NativeInt; 
    end; 
begin 
    Result := 0; 
    if A <> nil then 
    Result := PDynArrayRec(PByte(A) - SizeOf(TDynArrayRec))^.Length; 
end; 

{$POINTERMATH ON} 
type 
    PArray = ^Pointer; 
{$POINTERMATH OFF} 

procedure CopyArrayDeep(Dest, Source: PArray; TypeInfo: Pointer; Count: NativeInt); 
var 
    typeData: PTypeData; 
    elType: PPTypeInfo; 
    i: Integer; 
len : NativeInt; 
begin 
    if (Source = nil) or (Count = 0) then 
    Exit; 
    typeData := GetTypeData(TypeInfo); 
    elType := typeData.elType; 
    if (elType <> nil) and (elType^.kind = tkDynArray) then 
    begin 
    for i := 0 to Count-1 do 
    begin 
     len := DynArrayLength(Source[i]); 
     DynArraySetLength(Dest[i], elType^, 1,@len); 
     CopyArrayDeep(Dest[i], Source[i], elType^, len); 
    end; 
    end 
    else 
    if elType <> nil then 
     CopyArray(Dest, Source, elType^, Count) 
    else 
     Move(Source^, Dest^, Count * typeData.elSize); 
end; 

class function TArray.Clone<T>(const source: T): T; 
var 
    p: PTypeInfo; 
    count: NativeInt; 
    i: Integer; 
begin 
    p := TypeInfo(T); 
    if p.Kind <> tkDynArray then 
    raise ENotSupportedException.Create('type not supported'); 
    count := DynArrayLength(PArray(@source)^); 
    DynArraySetLength(PArray(@Result)^, p, 1,@count); 
    CopyArrayDeep(PArray(@Result)^, PArray(@source)^, p, count); 
end; 
+0

Обратите внимание на комментарии, сделанные @StefanGlienke, что можно было бы расширить его, чтобы включить вложенные управляемые типы (строки, динамические массивы и т. Д.). –

+1

Я не вижу, как это относится к вопросу –

+0

@DavidHeffernan Вопрос: «Как ускорить копирование общего массива», а мой ответ охватывает раздел «копия общего массива». Он охватывает тему плаката «Но это не очень хорошо сочетается с управляемыми типами». и «Какие у меня варианты?» Единственная часть, которая не является обложкой, - это проблема с ускорением, но поскольку нет времени, я не знаю, быстрее или нет, я сомневаюсь, что это так, поскольку она использует RTL, но это только догадка с моей стороны. Так что для меня это относится к вопросу много, но не отвечает на вопрос полностью, но без времени, как это можно сделать? –

Смежные вопросы