.NET + Копирование большого количества трюков с памятью


4

Еще в прежние времена использовались трюки (часто для блендинговых кадровых фонов), чтобы скопировать большие куски памяти из одного места в другое.

Теперь, когда я работаю на C#, я обнаружил необходимость перемещения массива байтов (размером примерно 32 тыс.) Из одного места памяти в другое примерно 60 раз в секунду.

Как бы то ни было, я не думаю, что байтовая копия байта в цикле for является оптимальной здесь.

Кто-нибудь знает хороший трюк, чтобы сделать этот вид работы, оставаясь в чисто управляемом коде?

Если нет, я готов сделать некоторые P/Invoking или перейти в небезопасный режим, но я бы хотел остаться управляемым, если можно, по причинам, связанным с платформой.

EDIT: Некоторые бенчмаркинг код, который я написал просто для удовольствия:

побайтно: 15.6192

4 байта в цикле: 15,6192

Block Copy: 0

Byte[] src = new byte[65535]; 
      Byte[] dest = new byte[65535]; 
      DateTime startTime, endTime; 

      startTime = DateTime.Now; 
      for (int k = 0; k < 60; k++) 
      { 
       for (int i = 0; i < src.Length; i++) 
       { 
        dest[i] = src[i]; 
       } 
      } 
      endTime = DateTime.Now; 

      Console.WriteLine("Byte by Byte: " + endTime.Subtract(startTime).TotalMilliseconds); 

      startTime = DateTime.Now; 
      for (int k = 0; k < 60; k++) 
      { 
       int i = 0; 
       while (i < src.Length) 
       { 
        if (i + 4 > src.Length) 
        { 
         // Copy the remaining bytes one at a time. 
         while(i < src.Length) 
         { 
          dest[i] = src[i]; 
          i++; 
         } 
         break; 
        } 

        dest[i] = src[i]; 
        dest[i + 1] = src[i + 1]; 
        dest[i + 2] = src[i + 2]; 
        dest[i + 3] = src[i + 3]; 

        i += 4;      
       } 
      } 
      endTime = DateTime.Now; 

      Console.WriteLine("4 Bytes per loop: " + endTime.Subtract(startTime).TotalMilliseconds); 

      startTime = DateTime.Now; 
      for (int k = 0; k < 60; k++) 
      { 
       Buffer.BlockCopy(src, 0, dest,0, src.Length); 
      } 
      endTime = DateTime.Now; 

      Console.WriteLine("Block Copy: " + endTime.Subtract(startTime).TotalMilliseconds); 
+1

System.Diagnostics.Stopwatch, очень классный класс, который может помочь. 24 сен. 082008-09-24 01:13:33

  0

Да, выбор времени с помощью Now довольно бесполезен, если вы не делаете намного больше повторений, чем здесь, чтобы получить общее время, используемое в пути. Теперь() только для каждой системы фиксируется каждые 64 секунды в секунду, так что все ваши тесты устанавливаются в том, что первые два составляют> 8 мс и последние <8 мс. 24 сен. 082008-09-24 01:24:15

8

Я думаю, вы можете рассчитывать на Buffer.BlockCopy (), Чтобы сделать правильную вещь

http://msdn.microsoft.com/en-us/library/system.buffer.blockcopy.aspx