Разбор текстового файла на BlackBerry занимает вечно - PullRequest
3 голосов
/ 22 октября 2010

Первоначально я использовал собственные методы синтаксического анализатора xml RIM для синтаксического анализа текстового файла размером 150 тыс., Примерно 5000 строк xml, однако это заняло около 2 минут, поэтому я попробовал формат на основе строки:

Название: Название книги
Строка 1
Строка 2
Линия 3

Я должен быть в состоянии прочитать файл за меньшее время, чем требуется, чтобы мигать, но он все еще медленный.

Идентификатор книги - это вектор объектов Книги, а строки хранятся в векторе строк в объекте Книги.

class classs = Class.forName("com.Gui.FileLoader");
InputStream is = classs.getResourceAsStream( fileName );

int totalFileSize = IOUtilities.streamToBytes( is ).length;
int totalRead = 0;

//Thought that maybe a shared input stream would be faster, in this case it't not.
SharedInputStream sis = SharedInputStream.getSharedInputStream( classs.getResourceAsStream( fileName ) );

LineReader lr = new LineReader( sis );
String strLine = new String( lr.readLine() );
totalRead += strLine.length();

Book book = null;

//Loop over the file until EOF is reached, catch EOF error move on with life after that.
while(1 == 1){

    //If Line = Title: then we've got a new book add the old book to our books vector.
    if (strLine.startsWith("Title:")){

        if (book != null){
            books.addElement( book );
        }

         book = new Book();

         book.setTitle( strLine.substring( strLine.indexOf(':') + 1).trim() );

         strLine = new String( lr.readLine() );
         totalRead += strLine.length();
         continue;
    }

    int totalComplete = (int) (  ( (double) totalRead / (double) totalFileSize ) * 100.00);
    _observer.processStatusUpdate( totalComplete , book.getTitle() );

    book.addLine( strLine );

    strLine = new String( lr.readLine(), "ascii" );
    totalRead += strLine.length();
}

Ответы [ 4 ]

4 голосов
/ 22 октября 2010

Во-первых, вы читаете файл дважды - один раз для определения размера, а затем снова для его анализа. Поскольку вы уже читаете его в байтовый массив для определения размера, почему бы не передать этот байтовый массив в конструктор ByteArrayInputStream? Например:

//Used to determine file size and then show in progress bar, app is threaded.
byte[] fileBytes = IOUtilities.streamToBytes( is );
int totalFileSize = fileBytes.length;
int totalRead = 0;

ByteArrayInputStream bais = new ByteArrayInputStream( fileBytes );
LineReader lr = new LineReader( bais);

Таким образом, не имеет значения, если остальные классы, читающие из потока, читают байт за раз - все это в памяти.

2 голосов
/ 22 октября 2010

Легко предположить, что все операции, которые вы исключили из примера кода, завершаются за постоянное время.Я предполагаю, что один из них делает что-то неэффективно, например, book.addLine( strLine ); или, возможно, _observer.processStatusUpdate( totalComplete , book.getTitle() );. Если эти операции не могут завершиться в постоянное время, вы могли бы легко иметь алгоритм квадратичного анализа.

Просто подумать об операциях - лучший способ понять это, но если вы озадачены, попробуйте использовать профилировщик BlackBerry.Запустите вашу программу в отладчике Eclipse и остановите ее на точке останова непосредственно перед синтаксическим анализом.Затем в Eclipse выберите «Окно .. Показать представление .. Другое .. BlackBerry .. BlackBerry Profiler View» Выберите кнопку «Параметры настройки» на панели инструментов представления профилировщика.У него синий треугольник на значке.Задайте для параметра «присвоение метода» значение «Накопительное», а для параметра «Что профилировать» - значение «Время, включая нативные методы»

, затем продолжите программу.По окончании синтаксического анализа вам нужно приостановить выполнение программы, а затем щелкнуть вкладку «Метод» представления профилировщика.Оттуда вы сможете определить свою болевую точку.

0 голосов
/ 22 октября 2010

Где, по словам профилировщика, вы проводите время?

Если у вас нет предпочтительного профилировщика, в Java 6 JDK есть jvisualvm.

(я думаю, вы найдете все время, потраченное на «чтениесимвол из файла ". Если это так, нужно буферизовать)

0 голосов
/ 22 октября 2010

Попробуйте использовать new BufferedInputStream(classs.getResourceAsStream(fileName));

РЕДАКТИРОВАТЬ:

Очевидно, документация , которая говорит, что они имеют BufferedInputStream неправильно .

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

...