Объект программирования для обработки больших списков данных - PullRequest
0 голосов
/ 07 января 2020

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

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

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

Существует ли конкретный c программный объект или парадигма, позволяющая обрабатывать большое количество больших коллекций, возможно, с довольно тяжелым пользовательским выбором / отображением logi c?

Я строю для Android используя Kotlin

1 Ответ

2 голосов
/ 07 января 2020

Прежде всего, когда мы говорим о производительности, есть только один правильный ответ - написать тест и тест.

О памяти: список с 1 000 000 уникальных String с со средним размером 30 символов потребуется около 120 Мб (например, 10 ^ 6 * 30 * 4, где последним является «размер символа», давайте подумаем, что это символ Unicode с 4 байтами). И, пожалуйста, добавьте 1-3% для обеспечения расходов, таких как ссылки ссылки. Поэтому: если у вас есть сотни String с, просто загрузите все данные в память и используйте список, потому что это самое быстрое решение (синхронное, неизменное и т. Д. c.).

Если вы можете сделать потоковые операции, вы можете использовать последовательности. Они довольно ленивы, то же самое с Java Streams и . Net Linq . Пожалуйста, посмотрите пример ниже, он требует небольшого объема памяти.

fun countOfEqualLinesOnTheSamePositions(path1: String, path2: String): Flow<String> {
    return File(path1).useLines { lines1 ->
        File(path2).useLines { lines2 ->
            lines1.zip(lines2)
                .map { (line1, line2) ->
                    line1 == line2
                }
                .count()
        }
    }
}

Если вы не смогли сохранить целые данные в памяти и не смогли работать с потоковой схемой, вы можете:

  • Алгоритм доработки для однопроходного или многократного прохода, каждый из которых похож на поток Например, Huffman Coding является двухпроходным алгоритмом, поэтому его можно использовать для сжатия 1 ТБ данных с использованием небольшого объема памяти.
  • Хранение промежуточных данных на диске (это очень много комплекс для этого короткого ответа).

Для дополнительных оптимизаций:

  • Чтобы охватить случай объединения большого количества параллельных потоков, пожалуйста, рассмотрите также Kotlin Поток . Это позволяет работать асинхронно, чтобы избежать блоков ввода-вывода. Например, это может быть полезно для объединения ~ 100 сетевых потоков.
  • Чтобы хранить в памяти много неуникальных элементов, рассмотрите cache logi c. Это может сэкономить память (однако, пожалуйста, сравните сначала).
  • Попробуйте работать с ByteBuffer с, а не String с. Вы можете получить гораздо меньше ресурсов (поскольку вы можете явно освободить объект), однако код будет слишком сложным.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...