Laden...

Schnelles kopieren eines Byte[]

Erstellt von Sascha M. vor 12 Jahren Letzter Beitrag vor 12 Jahren 1.268 Views
S
Sascha M. Themenstarter:in
143 Beiträge seit 2006
vor 12 Jahren
Schnelles kopieren eines Byte[]

Hi,

was ist Eurer Meinung die schnellste Möglichkeit ein byte[] in ein anderes zu kopieren? Im Moment verwende ich Buffer.BlockCopy. Es kann auch ruhig unsafe oder ein API Aufruf sein. Das ist nicht so wichtig. Performance ist das einzig wichtige Kriterium.

Gruß
Sascha

5.658 Beiträge seit 2006
vor 12 Jahren

Hi Sascha,

suchst du die Array.CopyTo Methode?

Christian

Weeks of programming can save you hours of planning

S
Sascha M. Themenstarter:in
143 Beiträge seit 2006
vor 12 Jahren

Hi,

habe ich schon getestet. Performance ist etwa schlechter als mit Buffer.BlockCopy.

1.130 Beiträge seit 2007
vor 12 Jahren
    [Jede Menge Sicherheitschecks...]
    if (count > 0) {
        // Call our faster version of memmove, not the CRT one.
        m_memmove(dst->GetDataPtr() + dstOffset, src->GetDataPtr() + srcOffset, count);
    }

[Deutlich mehr Abfragen und Sicherheitschecks]
if (r == AssignWillWork)
        {
            src = (BYTE*)gc.pSrc->GetDataPtr();
            dst = (BYTE*)gc.pDst->GetDataPtr();
            size = gc.pSrc->GetMethodTable()->GetComponentSize();
            g_IBCLogger.LogMethodTableAccess(gc.pSrc->GetMethodTable());
            m_memmove(dst + ((m_iDstIndex - destLB) * size), src + ((m_iSrcIndex - srcLB) * size), m_iLength * size);
            if (gc.pDst->GetMethodTable()->ContainsPointers())
            {
                GCHeap::GetGCHeap()->SetCardsAfterBulkCopy( (Object**) (dst + (m_iDstIndex * size)), m_iLength * size);
            }        
        }

Beide methoden benutzen "Reflection" (wenn auch in der nativen=schnelleren Variante), um zu prüfen, ob die Operation gültig ist.

Ich denke RtlMoveMemory könnte schneller sein, weil die ganzen Abfragen zur Laufzeit wegfallen.

Ansonsten gibts an platformunabängigen sachen noch cpblk, welches aber äußerst umständlich zu benutzen ist, oder man kann was eigenes mit unsafe schreiben, was dann aber tendenziell eher langsamer ist.

Fazit: Buffer.BlockCopy ist bequem und relativ schnell, ansonsten probier mal RtlMoveMemory.

Dennoch interressiert es mich, ob es nicht einen besseren weg gäbe dein Ziel zu erreichen, als massenweise Bytearrays umzokopieren. Dazu musst du aber mal den Anwendungsfall nennen!

Projekte:Jade, HttpSaver
Zum Rechtschreiben gibts doch schon die Politiker. Aber die bauen auch nur mist!

S
Sascha M. Themenstarter:in
143 Beiträge seit 2006
vor 12 Jahren

Der Anwendungsfall sieht so, dass ich eine gepackte Datei habe. Genauer gesagt, sind Blöcke darin gepackt und die muss ich zur Laufzeit entpacken. Ich muss z.B. Block 10 -12 entpacken und vom entpackten Block 10 ab Byte x bis Block 12 Byte y zurückgeben.

Gruß
Sascha

W
872 Beiträge seit 2005
vor 12 Jahren

Ich denke, Du musst schauen, dass Deine Funktionen ueberall mit den gleichen Parametern wie Buffer.Copy arbeiten -d.h. immer byte[], offset und Nutzlaenge benutzen, so dass Du immer mit dem relevanten Ausschnitt arbeitest, ohne jemals zu kopieren...

1.130 Beiträge seit 2007
vor 12 Jahren

Wenn die Daten an einem stück liegen ist das sicherleich die beste möglichkeit, aber wenn (wovon ich ausgegangen bin) die daten in mehreren häppchen fragmentiert sind, dann wird das sehr schnell sehr unhandlich.

Projekte:Jade, HttpSaver
Zum Rechtschreiben gibts doch schon die Politiker. Aber die bauen auch nur mist!