2010-07-23 3 views
4

В случае, если вы хотите сбросить массив логических значений, что быстрее, переназначение массива или перечисление и сброс значений?Redim boolean Array vs enumerate и set

Я провел несколько тестов, и они, похоже, предлагают, чтобы redim был намного быстрее, но я не уверен, что это не результат того, как я запускаю тесты.

Мои тесты показывают, что redim почти в два раза быстрее.

Так может ли кто-нибудь позаботиться о том, что быстрее и почему? Также ожидаете ли вы такого же результата на разных языках?

Enum Тест:

Dim booleanArray(200) As Boolean 

     Dim startTime As Date = Date.Now 

     For i As Integer = 0 To 9999999 
      For l As Integer = 0 To 200 
       booleanArray(l) = True 
      Next 
     Next 

     Dim endTime As Date = Date.Now 

     Dim timeTaken As TimeSpan = endTime - startTime 

Redim Тест:

Dim booleanArray(200) As Boolean 

     Dim startTime As Date = Date.Now 

     For i As Integer = 0 To 9999999 
      ReDim booleanArray(200) 
     Next 

     Dim endTime As Date = Date.Now 

     Dim timeTaken As TimeSpan = endTime - startTime 
+0

Почему это помечено как C#? –

+0

Потому что это примерно так же, как cv, поскольку речь идет о vb, мой пример просто является vb –

+0

@OP FYI - * ALLOT * должен читать * много * –

ответ

2

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

Однако обратите внимание, что это создаст новый массив со всеми элементами как False, а не True.

Более подходящий тест может состоять в том, чтобы вызвать Array.Clear в существующем массиве в первом случае, что довольно быстро уничтожит содержимое.

Обратите внимание, что ваша вторая форма будет создавать намного больше мусора - в этом случае она всегда будет оставаться в gen0 и будет легко собрана, но в реальных приложениях с более реалистичным использованием памяти вы можете в конечном итоге вызвать проблемы с сбором мусора создавая новые массивы вместо того, чтобы очищать старые.

Вот быстрый тест на C#, который тестирует три стратегии:

using System; 
using System.Diagnostics; 

public class Test 
{ 
    const int Iterations = 100000000; 

    static void Main() 
    { 
     TestStrategy(Clear); 
     TestStrategy(ManualWipe); 
     TestStrategy(CreateNew); 
    } 

    static void TestStrategy(Func<bool[], bool[]> strategy) 
    { 
     bool[] array = new bool[200]; 
     GC.Collect(); 
     GC.WaitForPendingFinalizers(); 
     Stopwatch sw = Stopwatch.StartNew(); 
     for (int i = 0; i < Iterations; i++) 
     { 
      array = strategy(array); 
     } 
     sw.Stop(); 
     Console.WriteLine("{0}: {1}ms", strategy.Method.Name, 
          (long) sw.ElapsedMilliseconds); 
    } 

    static bool[] Clear(bool[] original) 
    { 
     Array.Clear(original, 0, original.Length); 
     return original; 
    } 

    static bool[] ManualWipe(bool[] original) 
    { 
     for (int i = 0; i < original.Length; i++) 
     { 
      original[i] = false; 
     } 
     return original; 
    } 

    static bool[] CreateNew(bool[] original) 
    { 
     return new bool[original.Length]; 
    } 
} 

Результаты:

Clear: 4910ms 
ManualWipe: 19185ms 
CreateNew: 2802ms 

Однако, это по-прежнему только с помощью поколения 0 - я лично ожидал Clear быть лучше для общей производительности приложений. Обратите внимание, что они ведут себя по-другому, если какой-либо другой код имеет ссылки на исходный массив - стратегия «создать новый» (ReDim) вообще не изменяет существующий массив.

+0

ReDim не сохраняет существующий контент ... Redim Preserve делает ... Или вы имеете в виду, что контент остается где-то в памяти? –

+0

«Если вы не укажете' Preserve', 'ReDim' инициализирует элементы нового массива значением по умолчанию для своего типа данных." http://msdn.microsoft.com/en-us/library/w8k3cys2(VS.80).aspx – MarkJ

+0

Спасибо, Джон, не знаю, что бы мы сделали без четких и подробных ответов ... :-) –

0

я ожидал бы ReDim быть быстрее, так как вы не присваивание значения для каждого элемента массива ,

Микро-тест отображается в порядке.

+0

Он должен очистить содержимое массива. «Redim Preserve» сохранит содержимое (согласно моему пониманию VB6). – shahkalpesh

+0

@shahkalpesh - vb.net не vb6, но синтаксис redim тот же. – Oded

+0

Определенно. И они не изменили бы смысл заявления. – shahkalpesh

1

Испытания не сопоставимы.
Первый тест устанавливает для каждого элемента значение true, тогда как Redim этого не делает.

Redim помогает вам увеличить/уменьшить границы & очистить содержимое (и установить его по умолчанию). , например. Redim поможет установить для массива boolean значение false.

Ожидаете ли вы Redim, чтобы установить все элементы в true?

Dim booleanArray(200) As Boolean 

For l As Integer = 0 To 200 
    booleanArray(l) = True 
Next 

Redim booleanArray(200) 

Это приведет к сбросу содержание каждого элемента booleanArray к false.

Если вы хотите сохранить контент & увеличить размер - Redim Preserve booleanArray(300) (вместо Redim booleanArray(200)). Это сохранит первые 200 элементов до true, а новые 100 элементов будут иметь значение по умолчанию (false).

1

Я испытал это на языке С # 3,5

Время, затраченное на Enum Test: 00: 00: 06,2656 Время, затраченное на Redim Test: 00: 00: 00,0625000

Как вы можете видеть Redim является быстрее, поскольку вы не устанавливаете никаких значений для него.