Soru Hangisi daha iyi? dizi, ArrayList veya List (performans ve hız açısından)


Sayfamı işlemek için hızlı bir hıza ihtiyacım var. Eklenecek değerlerin sayısı dinamik olacaktır.

Yukarıdakilerden hangisi tercih edilir? Geçerli bir sebeple destek.

Düzenleme: Örneğin:

string str = "a,b,c"; //Count of the number of elements in str is not fixed
string[] arr = str.Split(',');

veya,

ArrayList al = new ArrayList();
al.Add(str.Split(','));

16
2018-05-30 11:39


Menşei


Neden kendin için denemiyorsun? Ayrıca, hepsi Array, ArrayList veya List <T> ile ne yapmak istediğinize bağlıdır. Çalışmak için en kolay olanı seçerim ve gerçekten ihtiyacınız olduğunda performans konusunda endişelenirim. - Kristof Claes
Özel durumunuzda her birini deneyin, profilinizi ve hangisinin size en uygun hizmeti sunduğunu görün. Her biri farklı amaçlar sunuyor. Tüm durumlara uyan genel bir 'bu en iyisi' cevabı yoktur. - Sam Holder
Sabahları [erken-optimizasyon] kokusunu seviyorum. - Jamiec
List<T> ve ArrayList destek depoları için diziler kullanın. Diziler kadar hızlı olabilirler (ve onlar) ama daha hızlı olamazlar. - dasblinkenlight
benzer stackoverflow.com/questions/128636/... - Tilak


Cevaplar:


List<T> genellikle tercih edilmelidir ArrayList

  • Bokstan kaçındığı için değer tipleri için daha hızlı.
  • güçlü yazılan öğeler

Arayanların değişmez olmasını istediğiniz listeleri istiyorsanız, bu ikisi tarafından da desteklenir. List<T> ve ArrayList:

List<T>.AsReadOnly()
ArrayList.ReadOnly(ArrayList list);

Senin soru arasında seçim soruyor ArrayList ve List<T>Ancak, örneğiniz, bir dizi de göstermez.


18
2018-05-30 11:53



Peki ArrayList'i ne zaman seçmek Listeden daha iyi bir seçenek olabilir? - eaglei22


"Değişmez" koleksiyonlar için dizi, List<T> değiştirilebilir koleksiyonlar için.

  • "Ölümsüz" koleksiyonu - sadece yaratımda değişti ve daha sonra pek çok okuma yapıldı.
  • Değişken koleksiyonu - birçok zaman değişiyor

Performans istatistikleri (Array vs List vs ReadonlyCollection):

       Array                List        ReadOnlyCollection         Penalties      Method
00:00:01.3932446    00:00:01.6677450    00:00:06.2444633    1 vs  1,2  vs  4,5   Generate
00:00:00.1856069    00:00:01.0291365    00:00:02.0674881    1 vs  5,5  vs 11,1   Sum
00:00:00.4350745    00:00:00.9422126    00:00:04.5994937    1 vs  2,2  vs 10,6   BlockCopy
00:00:00.2029309    00:00:00.4272936    00:00:02.2941122    1 vs  2,1  vs 11,3   Sort

Kaynak kodu:

interface IMethods<T>
{
  T Generate(int size, Func<int, int> generator);
   int Sum(T items);
   T BlockCopy(T items);
   T Sort(T items);
}

class ArrayMethods:IMethods<int[]>
{
  public int[] Generate(int size, Func<int, int> generator)
  {
    var items = new int[size];
    for (var i = 0; i < items.Length; ++i)
      items[i] = generator(i);
    return items;
  }
  public int Sum(int[] items)
  {
    int sum = 0;
    foreach (var item in items)
      sum += item;
    return sum;
  }
  public int[] BlockCopy(int[] items)
  {
    var res = new int[items.Length / 2];
    Buffer.BlockCopy(items, items.Length / 4 * sizeof(int), res, 0, res.Length * sizeof(int));
    return res;
  }
  public int[] Sort(int[] items)
  {
    var res = new int[items.Length];
    Buffer.BlockCopy(items, 0, res, 0, items.Length * sizeof(int));
    return res;
  }
}
class ListMethods : IMethods<List<int>>
{
  public List<int> Generate(int size, Func<int, int> generator)
  {
    var items = new List<int>(size);
    for (var i = 0; i < size; ++i)
      items.Add(generator(i));
    return items;
  }
  public int Sum(List<int> items)
  {
    int sum = 0;
    foreach (var item in items)
      sum += item;
    return sum;
  }
  public List<int> BlockCopy(List<int> items)
  {
    var count = items.Count / 2;
    var res = new List<int>(count);
    var start = items.Count / 4;
    for (var i = 0; i < count; ++i)
      res.Add(items[start + i]);
    return res;
  }
  public List<int> Sort(List<int> items)
  {
    var res = new List<int>(items);
    res.Sort();
    return res;
  }
}
class ReadOnlyCollectionMethods:IMethods<ReadOnlyCollection<int>>
{
  public ReadOnlyCollection<int> Generate(int size, Func<int, int> generator)
  {
    return new ReadOnlyCollection<int>(Enumerable.Range(0, size).Select(generator).ToList());
  }

  public int Sum(ReadOnlyCollection<int> items)
  {
    int sum = 0;
    foreach (var item in items)
      sum += item;
    return sum;
  }


  public ReadOnlyCollection<int> BlockCopy(ReadOnlyCollection<int> items)
  {
    return new ReadOnlyCollection<int>(items.Skip(items.Count / 4).Take(items.Count / 2).ToArray());
  }
  public ReadOnlyCollection<int> Sort(ReadOnlyCollection<int> items)
  {
    return new ReadOnlyCollection<int>(items.OrderBy(s => s).ToList());
  }
}

static class Program
{
  static Tuple<string, TimeSpan>[] CheckPerformance<T>(IMethods<T> methods) where T:class
  {
    var stats = new List<Tuple<string, TimeSpan>>();

    T source = null;
    foreach (var info in new[] 
      { 
        new {Name = "Generate", Method = new Func<T, T>(items => methods.Generate(10000000, i => i % 2 == 0 ? -i : i))}, 
        new {Name = "Sum", Method =  new Func<T, T>(items => {Console.WriteLine(methods.Sum(items));return items;})}, 
        new {Name = "BlockCopy", Method = new Func<T, T>(items => methods.BlockCopy(items))}, 
        new {Name = "Sort", Method = new Func<T, T>(items => methods.BlockCopy(items))}, 
        new {Name = "Sum", Method =  new Func<T, T>(items => {Console.WriteLine(methods.Sum(items));return items;})}, 
      }
     )
    {
      int count = 10;
      var stopwatch = new Stopwatch();
      stopwatch.Start();
      T res = null;
      for (var i = 0; i < count; ++i)
        res = info.Method(source);
      stopwatch.Stop();
      source = res;
      stats.Add(new Tuple<string, TimeSpan>(info.Name, stopwatch.Elapsed));
    }
    return stats.ToArray();
  }

  static void Main()
  {
    var arrayStats = CheckPerformance(new ArrayMethods());
    var listStats = CheckPerformance(new ListMethods());
    var rcStats = CheckPerformance(new ReadOnlyCollectionMethods());

    Console.WriteLine("       Array                List        ReadOnlyCollection         Penalties      Method");
    for(var i = 0; i < arrayStats.Length; ++i)
    {
      Console.WriteLine("{0}    {1}    {2}    1 vs {3,4:f1}  vs {4,4:f1}   {5}", arrayStats[i].Item2, listStats[i].Item2, rcStats[i].Item2, 
        listStats[i].Item2.TotalSeconds / arrayStats[i].Item2.TotalSeconds,
        rcStats[i].Item2.TotalSeconds / arrayStats[i].Item2.TotalSeconds, arrayStats[i].Item1);
    }
  }

17
2018-05-30 11:40



Dizi hariç gerçekten değişmez, IEnumerable<T> veya IReadOnlyList<T> (.Net 4.5'de yeni). - svick
Dizi değişmez değildir. Yerine kullanmak ReadOnlyCollection<T> değişmez bir sarıcı için List<T> - genellikle arayarak List<T>.AsReadOnly(). - Joe
Diziler değişebilir ve değişmezlik gerektiğinde kaçınılmalıdır: blogs.msdn.com/b/ericlippert/archive/2008/09/22/... - Joshua
@DarkGray, gerçektir, Array değişmez değildir, yani, yaratıldıktan sonra onu değiştirmek mümkündür (ör. myArray[i] = newValue). Performansa gelince, istatistikleriniz, ölçümleri nasıl yaptığını göstermediklerinden anlamsızdır. Sabit boyutlu olmak (yani, eleman ekleyemez / çıkaramaz) değişmez ile aynı değildir (yani mevcut elemanlar da değiştirilemez). - Joe
Bu testlerin bazıları kusurlu. Örneğin, Dizi için Oluştur işleviniz, boyutunun önceden biliniyor olduğu gerçeğini kullanır. Ancak, Liste oluşturunuzda benzer bir şey yapmıyorsunuz (örn. Kapasite argümanını List<T>Yapıcı). - Joe


List <T>  her zaman arraylist'ten daha hızlı olacak. List <T>'s onlara eklenen değerleri kutularına almanız gerekmez.

ArrayList sadece "nesneleri kabul et", yani listeye istediğiniz herhangi bir nesneyi ekleyebilmeniz için kutunun (CLR tarafından dolaylı olarak) ve daha sonra ihtiyaç duyduğunuzda tekrar açılmasının gerekeceği anlamına gelir. değerler.

Düzenle: işte güzel bir bağlantı


6
2018-05-30 11:43



Boks farkı sadece değer tipleri için geçerlidir. Referans türleri için ikisi eşit olacaktır. - Servy