Создание и анализ очень больших массивов в Java - PullRequest
0 голосов
/ 02 октября 2019

У меня есть CSV-файл, содержащий почти 2 миллиона строк с 3 столбцами (элемент, рейтинг, пользователь). Я могу перенести данные в 2D-массив строк или список. Однако моя проблема возникает, когда я пытаюсь проанализировать массивы для создания файлов CSV, потому что приложение останавливается, и я не знаю, как долго я должен ждать завершения программы.

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

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

Есть ли лучший способ обработкии рассчитать большие объемы данных, чтобы мое приложение не зависало?

Моя текущая программа выполняет следующие действия:

  1. Возьмите большой CSV-файл
  2. Разберите большойCSV-файл
  3. Создание двумерного массива, напоминающего исходный CSV-файл
  4. Создание списка отдельных элементов (каждый отдельный элемент представлен индексным номером)
  5. Создание списка отдельных пользователей (каждыйотдельный пользователь представлен индексным номером)
  6. Создать двумерный массив с индексами строк, представляющих элементы, индексами столбцов, представляющими пользователей, в результате чего получается массив [строка] [столбец] = рейтинг
  7. Рассчитать косинусное подобиедве матрицы
  8. Создание двумерного массива с индексами строк и столбцов, представляющих элементы, в результате чего получается массив [row] [column] = cosВ общем сходство

Я заметил, что моя программа зависает, когда она достигает шагов 4 и 5. Если я удалю шаги 4 и 5, она все равно будет зависать на шаге 6

Я прикрепил эту частьмоего кода

      FileInputStream stream = null;
      Scanner scanner = null;

      try{
         stream = new FileInputStream(fileName);
         scanner = new Scanner(stream, "UTF-8");
         while (scanner.hasNextLine()){
             String line = scanner.nextLine();
             if (!line.equals("")){
                String[] elems = line.split(",");
                if (itemList.isEmpty()){
                  itemList.add(elems[0]);
                }
                else{
                  if (!itemList.contains(elems[0]))
                     itemList.add(elems[0]);
                }
                if (nameList.isEmpty()){
                  nameList.add(elems[2]);
                }
                else{
                  if (!nameList.contains(elems[2]))
                     nameList.add(elems[2]);
                }
                for (int i = 0; i < elems.length; i++){
                   if (i == 1){
                     if (elems[1].equals("")){
                        list.add("0");
                      }
                      else{
                        list.add(elems[1]);
                      }
                   }
                   else{
                     list.add(elems[i]);
                   }
                }
             }
         } 
         if (scanner.ioException() != null){
            throw scanner.ioException();
         }
      }
      catch (IOException e){
         System.out.println(e);
      }
      finally{
         try{
            if (stream != null){
               stream.close();
            }
         }
         catch (IOException e){
            System.out.println(e);
         }
         if (scanner != null){
            scanner.close();
         }
      }

1 Ответ

0 голосов
/ 02 октября 2019

Вы можете попробовать установить -Xms и -Xmx . Если вы используете значения по умолчанию, возможно, вам просто нужно выделить больше памяти для JVM.

Кроме того, вы можете изменить свой код, чтобы он не воспринимал все как String. Для столбца score (который предположительно является числовым) вы должны иметь возможность проанализировать его как числовое значение и сохранить его вместо строкового представления. Почему? Строки используют намного больше памяти, чем числовые значения. Даже пустая строка использует 40 байтов , тогда как одно числовое значение может быть всего одним байтом .

Если один byte может работать (числовой диапазон от -128 до 127), тогда вы можете заменить ~ 80 МБ памяти на ~ 2 МБ. Даже использование int (4 байта) будет огромным улучшением по сравнению с String. Если в данных присутствуют другие числовые (или логические) значения, вы можете сделать дальнейшие сокращения.

...