2010-12-04 6 views
0

Я пытаюсь импортировать 30mb CSV файл в Core Data, используя CHCSVParser из https://github.com/davedelong/CHCSVParserКак ограничить использование памяти CHCSVParser?

Он работает, это было довольно легко установить, но она съедает много памяти, как это разбора через файл. Чрезмерное использование памяти, кажется, идет от конца -nextCharacter, в частности, призыв к -substringWithRange:

//return nil to indicate EOF or error 
if ([currentChunk length] == 0) { return nil; } 

NSRange charRange = [currentChunk rangeOfComposedCharacterSequenceAtIndex:chunkIndex]; 
NSString * nextChar = [currentChunk substringWithRange:charRange]; 
chunkIndex = charRange.location + charRange.length; 
return nextChar; 

я был в состоянии добавить autorelease пул к функции, которая вызывает -drain каждые 1000000 символов, но тогда пропускная способность идет вниз.

Есть ли у кого-нибудь другие идеи? Возможно, Дэйв ДеЛонг? :-)

+0

Пожалуйста, добавьте еще немного кода окружающего цикла и вашего авторизованного пула. – 2010-12-04 08:20:07

+0

Интересно! Я присмотрюсь и вернусь к вам. – 2010-12-06 00:04:18

ответ

1

ОК, поэтому я проверил все, и вы правы, есть довольно вопиющее наращивание памяти.

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

Что я в итоге сделал, это положить пул в метод -runParseLoop. Бассейн равен alloc 'd прямо перед циклом while и сливается сразу после. Там в unsigned short счетчик, который получает приращение в цикле, и в цикле, я -drain и повторно Alloc пул, если счетчик когда-либо хиты 0.

По существу:

NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 
unsigned short counter = 0; 
while (error == nil && 
     (currentCharacter = [self nextCharacter]) && 
     currentCharacter != nil) { 
    //process the current character 
    counter++; 
    if (counter == 0) { //this happens every 65,536 (2**16) iterations when the unsigned short overflows 
     //retain the characters that need to out-live this pool 
     [pool drain]; 
     pool = [[NSAutoreleasePool alloc] init]; 
     //autorelease the characters 
    } 
} 

[pool drain]; 

Это весело эксплуатация переполнения , а? :)

Я протестировал это против файла CSV 190 Мбайт, а использование памяти оставалось на разумных уровнях (пара мегабайт активной памяти).

Эти изменения были перенесены на главную ветвь на странице github. Попробуйте их, и дайте мне знать, как они работают на вас. Если у вас по-прежнему возникают проблемы с памятью/производительностью, вернитесь, и мы можем попробовать что-то еще.

Смежные вопросы