Сокращение объема памяти функции с большим количеством автоматически выпущенных переменных? - PullRequest
4 голосов
/ 07 октября 2010

Я все еще обдумываю некоторые нюансы управления памятью в target-C и придумал следующий случай, в котором я не уверен:

+ (NSDecimalNumber*)factorial: (NSDecimalNumber *)l {

    NSDecimalNumber *index = l;
    NSDecimalNumber *running = [NSDecimalNumber one];

    for (; [index intValue] > 1; index = [index decimalNumberBySubtracting:[NSDecimalNumber one]]) {
        running = [running decimalNumberByMultiplyingBy: index];
    }
    return running;
}

Здесь decimalNumberByMultiplyingBy и decimalNumberBySubtracting создадут много NSDecimalNumbers, которые со временем будут автоматически освобождены, насколько я понимаю, но я волнуюсь до тех пор, пока содержащаяся программа не будет зависать в огромном количестве памяти.

Должен ли я где-нибудь вводить пул автоматического выпуска? (Если да, то где?) Это окажет заметное влияние на производительность (по сравнению с побочным эффектом использования большого количества памяти)?

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

Это, вероятно, вопрос n00b, но я пытаюсь понять, какие из лучших практик в этой ситуации есть.

Ответы [ 3 ]

5 голосов
/ 07 октября 2010

Хорошей практикой является избегать создания большого количества автоматически выпущенных объектов за один проход цикла выполнения.Вы, кажется, уже знаете о решениях.Вы можете использовать неавторизованные объекты и освобождать их, когда закончите с ними.Вы также можете создать пул автоматического выпуска для разделов вашего кода, которые создают большое количество автоматически выпущенных объектов.Когда объект автоматически освобождается, он освобождается, когда пул автоматического освобождения вмещается.Использование пула автоматического выпуска будет выглядеть следующим образом:

NSAutoReleasePool *subPool = [[NSAutoreleasePool alloc] init];
// Code that generates a bunch of autoreleased objects.
[subPool release];

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

Дополнительные сведения см. В Руководстве по программированию управления памятью Apple для Какао.

1 голос
/ 07 октября 2010

Вы можете настроить пул автоматического выпуска в цикле, но зачем?

Вы не сможете накопить столько объектов в этом цикле, потому что вы вычисляете факториалы, и наибольший показатель степени, который может иметь NSDecimalNumber, равен 127.

Вы получите ошибку переполнения еще до того, как пройдете 100 итераций в цикле.

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

1 голос
/ 07 октября 2010

Лучший способ определить ответ - написать несколько разных способов и проверить. Я не думаю, что это будет проблемой, хотя NSDecimalNumbers будет максимально около 100, и 100 объектов NSDecimalNumber, вероятно, не будут иметь никакого значения.


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

while(/*condition*/) {
     NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    // code goes here

    [pool drain];
}
...