Мониторинг использования конкретных коллекций во время выполнения - PullRequest
0 голосов
/ 03 мая 2019

Справочная информация: Наше программное обеспечение Scala состоит из различных компонентов , разработанных различными командами , которые передают коллекции Scala туда и обратно.API обычно используют абстрактные коллекции, такие как Seq[T] и Set[T], и разработчики в настоящее время по существу свободны выбирать любую реализацию, которая им нравится: например, при создании новых экземпляров, некоторые идут с List() или Vector(), другие с Seq.empty.

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

Вопрос: Являются ли их какие-либо инструменты - в идеале Scala-конкретный, но JVM-общий также может быть в порядке - который может отслеживать использование во время выполнения коллекций и записывать информацию, необходимую для обнаружения и сообщения о нежелательных схемах доступа / использования коллекций?

Мне кажется,что мониторинг во время выполнения будет более плодотворным, чем статический анализ (включаяпростое связывание), потому что (i) статически определить шаблоны использования в горячем коде практически невозможно, и (ii) наиболее вероятно пропустить коллекции, которые были созданы внутри, например, при выполнении сложного фильтра / карты / сгиба / и т. д.операции с неизменяемыми коллекциями.

Редактирование / уточнение:

  • Изменение интерфейсов для принудительного применения определенных типов, таких как List, не является вариантом;это также не помешает чисто внутреннему использованию «неправильных» коллекций / шаблонов использования.

  • Цель состоит в том, чтобы определить глобально оптимальный (по многим прогонам программного обеспечения) тип коллекции, а не локально оптимизироватьдля каждого применяемого алгоритма

Ответы [ 2 ]

1 голос
/ 03 мая 2019

Для этого вам не нужно писать, не говоря уже о мониторинге времени выполнения. Это именно то, что делает язык со строгой типизацией для вас из коробки. Если вы хотите убедиться, что конкретный тип коллекции передается в API, просто объявите, что этот API принимает , что тип коллекции (например, def foo(x: Stream[Bar]), а не def foo(x: Seq[Bar]) и т. Д.).

В качестве альтернативы, если это практически возможно, просто преобразуйте в нужный тип как часть реализации: def foo(x: List[Bar]) = { val y = x.toArray ; lotsOfRandomAccess(y); }

Коллекции, которые «созданы внутри», обычно имеют тот же тип, что и родительский объект: List(1,2,3).map(_ + 1) возвращает List и т. Д. Опять же, если вы хотите убедиться, что используете определенный тип, просто скажите так:

 val mapped: List[Int] = List(1,2,3).map(_ + 1)

На самом деле, вы можете изменить шрифт таким образом, если в этом есть необходимость:

 val mappedStream: Stream[Int] = List(1,2,3).map(_ + 1)(breakOut)
0 голосов
/ 11 мая 2019

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

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

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


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

...