Один атом против нескольких ссылок

Каковы компромиссы представления состояния с использованием одного атома и хэш-карты по сравнению с несколькими ссылками?

Например:

(def start (atom {:location "Chicago" :employer "John"}))

vs

(def location (ref "Chicago"))
(def employer (ref "John"))

Большое спасибо


person user2936410    schedule 07.11.2013    source источник


Ответы (3)


Версия с одним атомом лучше и имеет меньше компромиссов. Учитывая, что вы не хотите менять работодателя и местоположение без согласования, ваша победа заключается в том, что вам не нужно создавать блок dosync, чтобы изменить либо местоположение, либо работодателя, либо и то, и другое. Используя атом, вы можете просто (swap! start assoc :location "baz").

Большой компромисс использования нескольких рефов заключается в том, что все транзакции с рефами будут пробоваться параллельно, и побеждает первый, кто готов, остальные будут перезапущены. Хотя это также верно для атомов, наличие большего количества ссылок для всех записей требует большего контроля, группировки (для блоков досинхронизации) и т. д. за кулисами. Чтобы было меньше перезапусков, имеет смысл сгруппировать информацию в хеш-карту. В зависимости от того, требуется ли скоординированное изменение, поместите его в ref или атом.

person Leon Grapenthin    schedule 07.11.2013

Множественные ссылки обеспечивают больший параллелизм, поскольку все записи в Atom линеаризуются. STM позволяет выполнять множество параллельных транзакций, когда нет конфликтующих записей/ensure (и, кроме того, он предоставляет commute, который позволяет выполнять определенные записи, которые обычно вызывают конфликт, чтобы этого не делать).

Кроме того, STM сотрудничает с агентами — действия, отправленные агентам из транзакции, будут выполняться тогда и только тогда, когда транзакция фиксируется. Это позволяет безопасно вызывать побочные эффекты внутри транзакции. Атомы не предлагают подобных возможностей.

Компромисс заключается в том, что накладные расходы STM больше, чем у Atom, плюс есть вероятность возникновения определенных аномалий (перекос записи, см. страница Википедии, посвященная изоляции моментальных снимков). Кроме того, можно добиться отличного параллелизма с STM, но при этом возникают серьезные проблемы с получением моментального снимка всей системы; в связи с этим см. превосходную запись в блоге Кристофа Гранда. и его библиотеку megaref.

Во многих сценариях люди считают, что достаточно просто хранить все состояние в одном атоме, и это определенно более простой и легкий подход.

person Michał Marczyk    schedule 07.11.2013
comment
+1 за сбалансированный ответ, но это меня немного смутило; Additionally, the STM cooperates with Agents -- actions sent to Agents from within a transaction will be performed if and only if the transaction commits. - Не будут ли выполняться действия при замене атома? Это означает, что действия будут выполняться независимо от успеха. - person muhuk; 09.11.2013
comment
Если вы send из функции, переданной swap!, то да, send будет выполняться повторно при каждой повторной попытке. Попробуйте, например. (def a (atom 0)) (def ag (agent nil)) (do (future (swap! a (fn [x] (Thread/sleep 5000) (send ag println :foo) (inc x)))) (Thread/sleep 1000) (swap! a inc)): здесь :foo будет напечатано дважды; если вы использовали Ref вместо Atom, он будет напечатан только один раз. - person Michał Marczyk; 09.11.2013

Я не думаю, что вам следует думать о компромиссах между atoms и refs, поскольку они используются для разных ситуаций.

Вы должны использовать atom, когда хотите изменить одну вещь атомарно.

refs использовать STM и включать в транзакцию одновременное изменение множества разных вещей.

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

  • Это единственная вещь, которую вы хотите/можете изменить за один шаг?
  • Это разные вещи, которые вы хотите/должны изменить транзакционно

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

Надеюсь, что различие поможет, для вашего примера я бы тем не менее использовал атом.

Здесь есть хорошее резюме с мотивами каждой стратегии.

person guilespi    schedule 07.11.2013