ऐसा लगता है कि यह संबंधित प्रदर्शन है: http://dev.clojure.org/jira/browse/CLJS-760
एक -reset के साथ एक IAtom प्रोटोकॉल जोड़ें! cljs.core/रीसेट में एटम के लिए विधि और एक तेज रास्ता!
jsperf यहाँ देखें - http://jsperf.com/iatom-adv
नवीनतम क्रोम और फ़ायरफ़ॉक्स संस्करणों पीड़ित ~ 20-30% मंदी। पुराने फ़ायरफ़ॉक्स संस्करण 60-70% तक पीड़ित हैं।
टिकट के नीचे, आईएटॉम को दो प्रोटोकॉल में विभाजित करने का निर्णय लिया गया: आईरसेट और आईएसएपीएपी। लेकिन यह कार्यान्वयन था कि डेविड के साथ चला गया, जो प्रकार की जांच करता है, और मुझे लगता है कि गति को वापस पाने के लिए किया गया था।
दुर्भाग्य से, यह स्पष्ट नहीं है क्यों एटम उस बात के लिए IReset (और ISwap) लागू करने के लिए नहीं किया गया था, और न ही क्यों उन चीजों के बजाय के लिए देखा नहीं थे। और यह स्पष्ट नहीं है कि मूल पैच कैसे काम करता है। यह मूल रूप से reset!
के कार्यान्वयन में ले लिया और एक instance
जांच के अंतर्गत रखें, और इसके लिए -reset!
पथ कहा:
diff --git a/src/cljs/cljs/core.cljs b/src/cljs/cljs/core.cljs
index 9fed929..c6e41ab 100644
--- a/src/cljs/cljs/core.cljs
+++ b/src/cljs/cljs/core.cljs
@@ -7039,6 +7039,9 @@ reduces them without incurring seq initialization"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Reference Types ;;;;;;;;;;;;;;;;
+(defprotocol IAtom
+ (-reset! [o new-value]))
+
(deftype Atom [state meta validator watches]
IEquiv
(-equiv [o other] (identical? o other))
@@ -7088,14 +7091,16 @@ reduces them without incurring seq initialization"
"Sets the value of atom to newval without regard for the
current value. Returns newval."
[a new-value]
+ (if (instance? Atom a)
(let [validate (.-validator a)]
(when-not (nil? validate)
- (assert (validate new-value) "Validator rejected reference state")))
+ (assert (validate new-value) "Validator rejected reference state"))
(let [old-value (.-state a)]
(set! (.-state a) new-value)
(when-not (nil? (.-watches a))
- (-notify-watches a old-value new-value)))
- new-value)
+ (-notify-watches a old-value new-value))
+ new-value))
+ (-reset! a new-value)))
(defn swap!
"Atomically swaps the value of atom to be:
यह 33692b79a114faf4bedc6d9ab38d25ce6ea4b295 (बहुत करीब या कम से कम कुछ) में प्रतिबद्ध है। और फिर अन्य प्रोटोकॉल परिवर्तन 3e6564a72dc5e175fc65c9767364d05af34e4968 में किया गया:
commit 3e6564a72dc5e175fc65c9767364d05af34e4968
Author: David Nolen <[email protected]>
Date: Mon Feb 17 14:46:10 2014 -0500
CLJS-760: break apart IAtom protocol into IReset & ISwap
diff --git a/src/cljs/cljs/core.cljs b/src/cljs/cljs/core.cljs
index 25858084..e4df4420 100644
--- a/src/cljs/cljs/core.cljs
+++ b/src/cljs/cljs/core.cljs
@@ -7061,9 +7061,12 @@ reduces them without incurring seq initialization"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Reference Types ;;;;;;;;;;;;;;;;
-(defprotocol IAtom
+(defprotocol IReset
(-reset! [o new-value]))
+(defprotocol ISwap
+ (-swap! [o f] [o f a] [o f a b] [o f a b xs]))
+
(deftype Atom [state meta validator watches]
IEquiv
(-equiv [o other] (identical? o other))
@@ -7124,21 +7127,33 @@ reduces them without incurring seq initialization"
new-value))
(-reset! a new-value)))
+;; generic to all refs
+;; (but currently hard-coded to atom!)
+(defn deref
+ [o]
+ (-deref o))
+
(defn swap!
"Atomically swaps the value of atom to be:
(apply f current-value-of-atom args). Note that f may be called
multiple times, and thus should be free of side effects. Returns
the value that was swapped in."
([a f]
- (reset! a (f (.-state a))))
+ (if (instance? Atom a)
+ (reset! a (f (.-state a)))
+ (-swap! a (deref a))))
([a f x]
- (reset! a (f (.-state a) x)))
+ (if (instance? Atom a)
+ (reset! a (f (.-state a) x))
+ (-swap! a (f (deref a) x))))
([a f x y]
- (reset! a (f (.-state a) x y)))
- ([a f x y z]
- (reset! a (f (.-state a) x y z)))
- ([a f x y z & more]
- (reset! a (apply f (.-state a) x y z more))))
+ (if (instance? Atom a)
+ (reset! a (f (.-state a) x y))
+ (-swap! a (f (deref a) x y))))
+ ([a f x y & more]
+ (if (instance? Atom a)
+ (reset! a (apply f (.-state a) x y more))
+ (-swap! a (f (deref a) x y more)))))
(defn compare-and-set!
"Atomically sets the value of atom to newval if and only if the
@@ -7149,13 +7164,6 @@ reduces them without incurring seq initialization"
(do (reset! a newval) true)
false))
-;; generic to all refs
-;; (but currently hard-coded to atom!)
-
-(defn deref
- [o]
- (-deref o))
-
(defn set-validator!
"Sets the validator-fn for an atom. validator-fn must be nil or a
side-effect-free fn of one argument, which will be passed the intended
यह मदद नहीं करता है कि टिकट दोहरे स्वभाव है: किस तरह से हालांकि स्पष्ट नहीं प्रदर्शन एक समस्या है (: "परमाणुओं काफी तेजी से काम कर नहीं कर रहे हैं ", या" रीसेट का उपयोग कर अन्य चीजें! पर्याप्त तेज़ नहीं चल रहे हैं "?) और एक डिज़ाइन समस्या (" हम एक आईटॉम प्रोटोकॉल चाहते हैं ")। मुझे लगता है कि मुद्दा यह था कि अन्य कार्यान्वयनों को सत्यापन को भुगतना होगा और वेचरर्स लागतों को सूचित करना होगा, भले ही वे वास्तव में परमाणु न हों। काश यह स्पष्ट था।
एक बात मैं Clojure/लिपि में प्रतिबद्ध के बारे में पसंद नहीं है कि वे बहुत वर्णनात्मक नहीं हो रहा है। मेरी इच्छा है कि वे उचित पृष्ठभूमि की जानकारी के साथ अधिक कर्नेल की तरह हों ताकि लोगों (जैसे हमारे) यह पता लगाने की कोशिश कर रहे हों कि चीजों को इसके बारे में और अधिक उपयोगी जानकारी कैसे मिली।