Улучшение производительности Java-программы - PullRequest
3 голосов
/ 17 февраля 2012

Я создал утилиту поиска апплета, в которой я предоставляю строку в качестве входных данных и нахожу эту строку в указанном файле или папке.Я сделал с этим, но я не доволен его работой.Процесс занимает слишком много времени, чтобы ответить.Я решил выполнить его профилирование, чтобы увидеть, что происходит, и заметил, что метод scanner.hasNextLine () занимает большую часть времени.Хотя это очень важный метод для моей программы, потому что я должен прочитать все строки и найти эту строку, есть ли другой способ улучшить его производительность и сократить время выполнения

Вот код, где я использую этот метод ....

fw = new FileWriter("filePath", true);
        bw = new BufferedWriter(fw);

        for (File file : filenames) {
            if(file.isHidden())
                continue;

                if (!file.isDirectory()) {
                Scanner scanner = new Scanner(file);
                int cnt = 0;
                while (scanner.hasNextLine()) {
                    String line = scanner.nextLine();
                    if(!exactMatch)
                    {
                        if(!caseSensitive)
                        {
                            if (line.toLowerCase().contains(searchString.toLowerCase())) {
                                // System.out.println(line);
                                cnt += StringUtils.countMatches(line.toLowerCase(),
                                        searchString.toLowerCase());
                            }
                        }
                        else
                        {
                            if (line.contains(searchString)) {
                                // System.out.println(line);
                                cnt += StringUtils.countMatches(line,
                                        searchString);
                            }
                        }
                    }

И да, метод toLowerCase () также занимает больше времени, чем ожидалось.


Я изменил свой код, и теперь я использую BufferedReader вместо Scanner, как Alex и Nrj , и я обнаружил хорошее улучшение производительности моегоприложение.Сейчас он обрабатывает в третий раз свою более раннюю версию.Спасибо всем, что ответили .....

Ответы [ 5 ]

3 голосов
/ 17 февраля 2012

После вашего вопроса я проверил код Scanner и думаю, что вы правы. Он не оптимизирован для работы с большими данными. Я бы порекомендовал вам использовать простые BufferedReader, которые обертывают InputStreamReader, которые обертывают FileInputStream:

BufferedReader r = new BufferedReader(new InputStreamReader(new FileInputStream(fileName)))

затем прочитайте построчно:

r.readLine()

Если этого недостаточно, попробуйте прочитать серии строк, а затем обработать их.

Относительно toLowerCase() вы можете попробовать вместо этого использовать регулярные выражения. Преимущество заключается в том, что вам не нужно каждый раз менять регистр строки. Недостатком является то, что в простых случаях регулярное выражение работает немного медленнее, чем обычное сравнение строк.

1 голос
/ 17 февраля 2012

(Только небольшие оптимизации, в ответ на комментарий выше.)

            if(!caseSensitive)
            {
                searchString = searchString.toLowerCase();
            }
            while (true) {
                String line = bufferedReader.readLine();
                if (line == null)
                    break;
                if(!caseSensitive)
                {
                    line = line.toLowerCase();
                }
                if(!exactMatch)
                {
                    if (line.contains(searchString)) {
                        // System.out.println(line);
                        cnt += StringUtils.countMatches(line,
                                searchString);
                    }
                }
1 голос
/ 17 февраля 2012

Я бы предложил перестроить ваше решение и использовать что-то вроде Lucene, чтобы выполнить поиск для вас. Вы можете индексировать и искать файлы с помощью Lucene гораздо более эффективно, руководство по тому, как это сделать с текстовыми файлами, можно найти здесь: http://www.avajava.com/tutorials/lessons/how-do-i-use-lucene-to-index-and-search-text-files.html

0 голосов
/ 17 февраля 2012
  1. Попробуйте использовать BufferedReader

  2. Используйте темы. Вы можете искать файлы параллельно, что должно сократить время поиска.

0 голосов
/ 17 февраля 2012

Я бы не использовал Java для поиска в файловой системе совпадений строки.Вместо этого вызовите собственный алгоритм из Java.Я бы вызвал grep из Java, используя что-то вроде этого:

ProcessBuilder pb = new ProcessBuilder("grep", "-r", "foo");
pb.directory(new File("myDir"));
Process p = pb.start();
InputStream in = p.getInputStream();
//Do whatever you prefer with the stream
...