Scala преимущества Seq.newBuilder перед Seq vars - PullRequest
0 голосов
/ 03 апреля 2020

В настоящее время в моем приложении я использую var fooSeq: Seq[Foo] = Seq.empty, а затем :+ для добавления элементов. Я понимаю, что это может привести к проблемам многопоточности и потенциальным условиям гонки, но до сих пор не было никаких проблем.

Я недавно обнаружил Seq.newBuilder() и, кажется, это может быть предпочтительным способом использования Scala последовательностей. Мне интересно, является ли выигрыш в производительности перед использованием vars и любых других видов преимуществ, которые он может принести

1 Ответ

1 голос
/ 03 апреля 2020

В общем, если вас интересует безопасность потоков, то общепринятым подходом является использование Java AtomicReference для переноса изменяемой переменной следующим образом:

val fooSeq: AtomicReference[Seq[Foo]] = new AtomicReference(Seq.empty)

и это было бы лучшим подходом, если вам нужны промежуточные результаты вместо того, чтобы идти с Строителем.

Если вам не нужны промежуточные результаты, тогда Строители, как правило, лучше. (Хотя, как упоминает Луис Мигель в комментарии, Builders являются внутренне изменяемыми и не обязательно ориентированными на многопотоковое исполнение)

Третий вариант - использовать изменяемую структуру данных из Scala collections: https://docs.scala-lang.org/overviews/collections/performance-characteristics.html

Возможно, вас заинтересует: MutableList, однако для обеспечения безопасности потоков все равно потребуется оболочка AtomicReference, если это является проблемой. Существуют некоторые структуры данных, которые изначально ориентированы на многопоточность, например TrieMap, и они доступны в collections.concurrent

...