- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试获取 the "official" example of clojure concurrency更接近使用手动锁定的 java 版本。 In this gist我放置了所有版本的 VisualVm 配置文件的 java 和 clojure 代码以及线程转储。
这是clojure代码和时间
(ns simple-example (:gen-class))
(set! *warn-on-reflection* true)
;; original from: http://clojure.org/concurrent_programming
(import '(java.util.concurrent Executors Future)
SimpleLocking$Node)
(defn test-concur [iter refs nthreads niters]
(let [pool (Executors/newFixedThreadPool nthreads)
tasks (map (fn [t]
(fn []
(dotimes [n niters]
(iter refs t))))
(range nthreads))]
(doseq [^Future future (.invokeAll pool tasks)]
(.get future))
(.shutdown pool)))
(defn test-stm [nitems nthreads niters]
(let [refs (vec (map ref (repeat nitems 0)))
iter #(dosync (doseq [r %] (alter r + 1 %2)))]
(test-concur iter refs nthreads niters)
(map deref refs)))
(defn test-atom [nitems nthreads niters]
(let [refs (vec (map atom (repeat nitems 0)))
iter #(doseq [r %] (swap! r + 1 %2))]
(test-concur iter refs nthreads niters)
(map deref refs)))
;; SimpleLocking$Node is the class with the synchronized method of java version
(defn test-locking [nitems nthreads niters]
(let [refs (->> (repeatedly #(SimpleLocking$Node.))
(take nitems) vec)
iter #(doseq [^SimpleLocking$Node n %] (.sum n (+ 1 %2)))]
(test-concur iter refs nthreads niters)
(map (fn [^SimpleLocking$Node n] (.read n)) refs)))
(definterface INode
(read [])
(add [v]))
(deftype Node [^{:unsynchronized-mutable true} value]
INode
(read [_] value)
(add [this v] (set! value (+ value v))))
(defn test-locking-native [nitems nthreads niters]
(let [refs (->> (repeatedly #(Node. 0))
(take nitems) vec)
iter #(doseq [^Node n %]
(locking n (.add n (+ 1 %2))))]
(test-concur iter refs nthreads niters)
(map (fn [^Node n] (.read n)) refs)))
(defn -main [& args]
(read-line)
(let [[type nitems nthreads niters] (map read-string args)
t #(apply + (time (% nitems nthreads niters)))]
(case type
'lock (println "Locking:" (t test-locking))
'atom (println "Atom:" (t test-atom))
'stm (println "STM:" (t test-stm))
'lock-native (println "Native locking:" (t test-locking-native)))))
Java version
int nitems=100;
int nthreads=10;
final int niters=1000;
Sum node values: 5500000
Time: 31
simple-example=> (-main "lock" "100" "10" "1000")
"Elapsed time: 60.030324 msecs"
Locking: 5500000
nil
simple-example=> (-main "atom" "100" "10" "1000")
"Elapsed time: 202.309477 msecs"
Atom: 5500000
nil
simple-example=> (-main "stm" "100" "10" "1000")
"Elapsed time: 1830.568508 msecs"
STM: 5500000
nil
simple-example=> (-main "lock-native" "100" "10" "1000")
"Elapsed time: 159.730149 msecs"
Native locking: 5500000
nil
>SimpleExampleMVar 100000 1000 6
Starting...
2100000000
Computation time: 11.781 sec
Done.
>SimpleExampleSTM 100000 1000 6
Starting...
2100000000
Computation time: 53.797 sec
Done.
>java -cp classes SimpleLocking
Sum node values: 2100000000
Time: 15.703 sec
java -cp classes;%CLOJURE_JAR% simple_example lock 1000 6 100000
"Elapsed time: 27.545 secs"
Locking: 2100000000
java -cp classes;%CLOJURE_JAR% simple_example lock-native 1000 6 100000
"Elapsed time: 80.913 secs"
Native locking: 2100000000
java -cp classes;%CLOJURE_JAR% simple_example atom 1000 6 100000
"Elapsed time: 95.143 secs"
Atom: 2100000000
java -cp classes;%CLOJURE_JAR% simple_example stm 1000 6 100000
"Elapsed time: 990.255 secs"
STM: 2100000000
最佳答案
您并没有真正将其与此处进行比较 - Clojure 版本正在创建和交换新的不可变盒装数字,而 Java 版本只是碰撞可变原语 int
同步方法中的计数器。
您可以在 Clojure 中执行普通的 Java 样式手动锁定,方法如下:
(locking obj (set! (. obj fieldName) (+ 1 (.fieldName obj)))))
locking
构造实际上等效于 Java
synchronized
代码块。
:unsynchronized-mutable
的 Clojure deftype 执行此操作那么我认为你应该能够匹配纯Java同步性能。
long
计数器等,这可能很有用)
关于performance - clojure "official"并发示例的可能改进(使用锁、原子、stm),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12484250/
我正在对 JVM 上的 STM 技术进行一些研究。阅读了一些文档后,我对 Multiverse 的实现有些困惑。 根据 the Multiverse FAQ , Multiverse 不支持检测。然而
我想知道 Clojure 怎么可能已经实现了软件事务内存并且没有发现任何问题,而微软没有完成它的 C# 工作并注意到一些问题使得实现这里描述的 STM 不切实际: http://www.bluebyt
最后,我有以下设置 C:>哪里玩 C:\apps\play-2.2.0\play C:\apps\play-2.2.0\play.bat C:> 哪里 scala C:\apps\scala\bin\
我试图找出 Clojure 所称的 STM 与 Haskell 中实现的 STM 之间的区别。撇开实际的语言语义差异不谈,正如 Rich Hickey 在他的演讲中所说,Clojure 的 STM 实
阅读 Bartosz Milewski 的精彩作品 blog post在 STM 上,我很兴奋地阅读了以下内容: But take into account an important fact: ST
大家好, 在某些时候,我认为这些 stm 实现(我使用过一点点的多元宇宙......),被过度宣传了。因为在某些时候他们使用 CAS 来为他们提供操作的原子性。如果我直接使用 CAS 而不是使用这些实
haskell 的 stm 库中有一个函数,其类型签名如下: alwaysSucceeds :: STM a -> STM () 根据我对 Haskell 中 STM 的了解,在执行 STM 计算时,
在 Clojure 中,我们使用 STM 来实现并发。 我的问题是STM使用数据的时间点值,这是否会带来歧义? 我们如何知道访问了什么值? 最佳答案 Clojure 中的 STM 提供了(通过 ref
我需要有关用作原子更改日志的数据结构的建议。 我正在尝试实现以下算法。有流量传入更改更新内存中的映射。在类似 Haskell 的伪代码中它是 update :: DataSet -> Some
我正在尝试对这两个(软件事务内存和原子操作,我想两者不一样)进行一些基准测试,尽管我没有使用STM做太多事情(它似乎很难使用),但我成功地尝试了对基准测试进行计数,即所有线程将共享计数器递增 5000
我能够使用 STM 初始化状态并将其打印出来: module Main where import Control.Concurrent.STM data State = State {name ::
我读过两个关于 STM 如何实现的完全不同的描述。也许两者都是正确的,或者一个是错误的,我希望有人能阐明这一点。 Take 1(维基百科):允许所有线程修改共享内存,但事务中的每次读写都会被记录下来。
我知道将具有副作用的函数放在 STM 事务中通常是不好的做法,因为它们可能会被重试和调用多次。 然而,在我看来,您可以使用代理来确保只有在事务成功完成后才会执行副作用。 例如 (dosync //
我正在编写一个程序,其中大量代理监听事件并对其使用react。由于Control.Concurrent.Chan.dupChan已弃用我决定使用 TChan 的广告。 TChan 的表现比我预想的差很
我正在研究 Clojure 中的并发编程。 http://clojure.org/concurrent_programming 我了解到atom、ref和agent形式是用来维护程序状态的。 仅ref
你好,我正在阅读《clojure 的乐趣》这本书,在关于 STM 的部分中,他们有一个 2 个事务的图像,其中 A 最初从引用中检索与 B 相同的值,然后事务 A 和 B 都进行计算但 A 首先完成并
我熟悉Database transactions ,并花费了大量的时间调整isolation levels 。我从未在代码中实现过自己的事务模型。 我已通读 the source code对于 Clo
我有一个事务由于某种原因无限期失败,我想在内部使用跟踪指令。例如,要在执行此片段中的事务之前打印 MVar 的状态: data_out do putTMVar
当我们运行 STM 表达式时,它命中了 retry,线程被阻塞,如果条目被修改,事务将再次运行。 但我想知道: 如果我们读取一个 STM 变量,但在导致重试的特定分支中实际未使用该变量,更新它是否会尝
我正在研究 Clojure 中的并发编程。 http://clojure.org/concurrent_programming 我了解到atom、ref 和agent 表单用于维护程序状态。 只有 r
我是一名优秀的程序员,十分优秀!