NSMutableArray initWithCapacity niuanse

Czy ktoś ma rady jak najlepiej zainicjować nsmutablearray jeśli chodzi o dyktowanie pojemności? Dokumentacja wspomina, że "...nawet jeśli podczas tworzenia tablicy określisz Rozmiar, określony rozmiar jest traktowany jako "podpowiedź"; rzeczywisty rozmiar tablicy nadal wynosi 0."Więc...

1) Czy jeśli init z większą pojemnością niż zazwyczaj używam, nie muszę martwić się o zmarnowaną pamięć?

2) Jeśli init o pojemności zazwyczaj niższej niż to, co używam, czy musisz martwić się o dłuższy czas przetwarzania, przeznaczając więcej pamięci na przechowywanie dodatkowych elementów?

Jak wpływa ta inicjalizowana pojemność na wydajność / zużycie pamięci tego typu danych?

Author: skaffman, 2010-10-16

2 answers

To, czy jakakolwiek przestrzeń jest marnowana przez zbyt dużą pojemność, jest w rzeczywistości szczegółem implementacji, którego Apple celowo nie ujawnia, tak myślę. Nsmutablearray jest klastrem klas, co oznacza, że w rzeczywistości nie otrzymujesz instancji NSMutableArray, ale jakiejś innej, wyspecjalizowanej klasy podążającej za tym samym interfejsem. A Apple nie mówi, która klasa zostanie zwrócona w jakim przypadku i jak się zachowuje. Więc trudno tu dać prawdziwe Rady.

Jeśli naprawdę wiesz, że średnio będziesz potrzebujesz pojemności X , po prostu użyj. W przeciwnym razie, jeśli nie masz problemów z wydajnością, w ogóle nie dbałbym o pojemność i po prostu użyj [NSMutableArray array]...

 15
Author: DarkDust,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-10-16 07:56:25

Matt Gallagher napisał dość pouczający artykuł na temat klas kolekcji Cocoa, wraz z kilkoma benchmarkami (z i bez initWithCapacity:, a także porównaniami między klasami) [13]}

Http://cocoawithlove.com/2008/08/nsarray-or-nsset-nsdictionary-or.html

Jego test (źródło dostępne) dla NSMutableArray długość 1.000.000 trwało 0.582256 s bez pojemności i tylko 0.572139 s z pojemności .

Test                                       | Time
[NSMutableArray array]                     | 0.582256 seconds
[NSMutableArray arrayWithCapacity:1000000] | 0.572139 seconds
Iterating contents                         | 0.004713 seconds
Powiedziałbym, że w 99% przypadków użycia jest w porządku. Jeśli jednak znasz rzeczywisty rozmiar tablicy wynikowej, nie zaszkodzi użyć [NSMutableArray arrayWithCapacity:].


I jeszcze Ten artykuł autorstwa Petera Ammona (który jest programistą w zespole AppKit/Foundation firmy Apple) z kilkoma wnikliwymi benchmarkami:

Http://ridiculousfish.com/blog/archives/2005/12/23/array/


Edit (Marzec 12. 2012):

Więcej informacji na temat wydajności inicjalizacji tablicy z http://darkdust.net/writings/objective-c/nsarray-enumeration-performance

[ ... ] ja [=>DarkDust] również chciałem wiedzieć, czy wydajność jest inna w zależności od tego, jak tablica została utworzona. Przetestowałem dwie różne metody:

  • Utwórz tablicę C, która odwołuje się do instancji obiektu i utwórz tablicę za pomocą initWithObjects:count:.
  • utworzyć NSMutableArray i następnie Dodaj obiekty za pomocą addObject:.

[...] jest różnica przy przydzielaniu: the initWithObjects:count: metoda jest szybsza . Z bardzo dużą liczbą obiektów, różnica ta może stać się znacząca.


Edit (6 marca 2014):

Kolejny wgląd w Wydajność inicjalizacji tablicy z http://ciechanowski.me/blog/2014/03/05/exposing-nsmutablearray/:

Przydzielmy nowe tablice o początkowej pojemności ustawionej na kolejne potęgi dwóch:

for (int i = 0; i < 16; i++) {
    NSLog(@"%@", [[[NSMutableArray alloc] initWithCapacity:1 << i] explored_description]);
}

Niespodzianka niespodzianka:

size:  2 // requested capacity:   1
size:  2 // requested capacity:   2
size:  4 // requested capacity:   4
size:  8 // requested capacity:   8
size: 16 // requested capacity:  16
size: 16 // requested capacity:  32
size: 16 // requested capacity:  64
size: 16 // requested capacity: 128
...
// 'size: 16' all the way down
 40
Author: Regexident,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-06 13:12:58