锘??xml version="1.0" encoding="utf-8" standalone="yes"?>
鍙橀噺鍜屽叏灞鐜
Clojure鏄釜寰堝疄鐢ㄧ殑璇█錛屽伓灝旈渶瑕佸皢緇存姢鍜屾敼鍙樻暟鎹殑鍊箋傚ス鎻愪緵浜?縐嶄笉鍚岀殑鏂瑰紡鏉ユ搷浣滃彉閲忥細Vars, Refs, Agents, 鍜孉toms銆俈ars鏈哄埗鏄槸鎸囧悜涓涓彲鏀瑰彉鐨勬暟鎹殑浣嶇疆錛屼綘鍙互涓烘瘡涓嚎紼嬪姩鎬佺殑緇戝畾錛堝埗瀹氫竴涓柊鐨勫瓨鍌ㄤ綅緗級涓涓柊鍊箋俈ars鍙互鍒濆鍖栨牴緇戝畾(涓嶆槸蹇呴』鐨?錛岀粦瀹氱殑鍊煎浜庢墍鏈夌嚎紼嬮兘鏄叡浜殑錛屼絾鍗村埆鐨勭嚎紼嬪氨涓嶈兘閲嶆柊緇戝畾銆傚洜姝わ紝瑕佷箞Var鍙互涓烘瘡涓嚎紼嬬粦瀹氬鹼紝瑕佷箞浣跨敤鏍圭粦瀹氥?/p>
涓嬮潰鐨剆pecial form def 鍒涘緩浜嗕竴涓猇ar錛屽鏋淰ar涓嶅瓨鍦ㄥ拰娌℃湁緇欏垵濮嬪寲錛寁ar灝辨槸涓嶇粦瀹氱殑錛堜笉鍏佽鍒涘緩闈炲姩鎬佺殑Var錛屽繀欏繪樉寮忔寚瀹氭牴緇戝畾錛夛細
user=> (def x)
#'user/x
user=> x
java.lang.IllegalStateException: Var user/x is unbound.
涓烘牴鍊煎垵濮嬪寲錛堝鏋滃瓨鍦紝灝辮鍐嶆緇戝畾錛?/p>
user=> (def x 1)
#'user/x
user=> x
1
榛樿鎯呭喌涓?瀹氫箟鐨勬椂鍊欏垵濮嬪寲浜嗘牴緇戝畾錛夛紝Vars鏄潤鎬佺殑(static)錛屼絾鏄紝寤虹珛鍔ㄦ乂ar鐨勫畾涔夊彲浠ラ氳繃鍏冩暟鎹爣璁扮殑鏂瑰紡錛岀劧鍚庡湪綰跨▼鐢ㄦ椂閫氳繃binding鏉ユ寚瀹氥?/p>
user=> (def ^:dynamic x 1)
user=> (def ^:dynamic y 1)
user=> (+ x y)
2
user=> (binding [x 2 y 3]
(+ x y))
5
user=> (+ x y)
2
binding琚垱寤哄悗鍏朵粬綰跨▼鏄槸涓嶅彲瑙佺殑銆傚垱寤虹殑binding鍙互琚祴鍊鹼紝涔熷氨鏄湪娌℃湁紱誨紑璋冪敤鍫嗘爤涔嬪墠鍙互琚笂涓嬫枃璁塊棶銆傚彲浠ュ湪涓鍧椾唬鐮佷箣鍓嶈緗甿atadata鏍囩:dynamic鏉ユ寚瀹?
user=> (def ^:dynamic x 1)
#'user/x
user=> (meta #'x)
{:ns #<Namespace user>, :name x, :dynamic true, :line 30, :file "NO_SOURCE_PATH"}
user=> (binding [x 2] (println x))
2
nil
user=> x
1
user=>
濡傛灉浣犳兂璁╁嚱鏁扮紪璇戜負static鐨勶紝騫朵笖鎸囧畾榪斿洖鍊鹼紝鍙互鐪嬩笅闈㈢殑渚嬪瓙(閫熷害鎻愬崌涓嶅皯錛屽叧閿殑璋冪敤鍑芥暟鍙互閲囩敤榪欑鏂瑰紡鍔犻?錛?/p>
(defn fib [n] (if (<= n 1)
1
(+ (fib (dec n)) (fib (- n 2)))))
#'user/fib
(defn ^:static fib2 ^long [^long n]
(if (<= n 1)
1
(+ (fib2 (dec n)) (fib2 (- n 2)))))
#'user/fib2
user=> (time (fib 38))
"Elapsed time: 1831.113 msecs"
63245986
user=> (time (fib2 38))
"Elapsed time: 328.715 msecs"
63245986
user=> (meta (var fib))
{:arglists ([n]), :ns #<Namespace user>, :name fib, :line 1, :file "NO_SOURCE_PATH"}
user=> (meta (var fib2))
{:arglists ([n]), :ns #<Namespace user>, :name fib2, :static true, :line 4, :file "NO_SOURCE_PATH"}
user=>
鍦ㄤ笂涓嬫枃涓彲鑳介渶瑕侀噸瀹氫箟闈欐佸彉閲忥紝浠嶤lojure1.3寮濮嬫彁渚?a style="color: #546188; ">with-redefs鍜?a style="color: #546188; ">with-redefs-fn榪欎袱涓畯鏉ヤ慨鏀廣?/p>
瀹氫箟鍑芥暟鐨?a style="color: #546188; ">defn涔熸槸Vars鐨勫瓨鍌ㄦ柟寮忥紝涔熷彲浠ュ湪榪愯鏃惰閲嶅畾涔夈傝繖涔熶負aop緙栫▼甯︽潵寰堝鏂逛究錛屼緥濡傦細浣犲彲浠ュ皝瑁呬竴涓被浼糽ogging鍑芥暟緇欒皟鐢ㄧ殑涓婁笅鏂囨垨鑰呮垨鑰呯嚎紼嬨?/p>
(set! var-symbol expr)
灝哣ars鎸囧畾涓簊pecial form
褰撳湴涓涓搷浣滅涓簊ymbol鐨勬椂鍊欙紝瀹冨繀欏繪槸鍏ㄥ眬鍙橀噺銆傚綋鍓嶇嚎紼嬬粦瀹氱殑鍊煎氨鏄悗闈㈢殑expr錛屼篃灝辨槸璇村繀欏繪槸Thread-local鐨勬墠鍙互錛屽惁鍒欏皢浼氭姏鍑轟竴涓嬌鐢╯et!鏉ヨ瀹氭牴緇戝畾鍙橀噺鐨勯敊璇傚彉閲忕殑琛ㄨ揪寮廵xpr蹇呴』鏈夎繑鍥炲箋?/p>
娉ㄦ剰錛屼綘涓嶈兘璧嬪肩粰涓涓嚱鏁扮殑鍙傛暟鎴栬呮湰鍦扮粦瀹氾紝鍙兘鏄痡ava鐨勫瓧孌礦ars Refs鍜孉gents錛屽洜涓鴻繖浜涙暟鎹湪Clojure閲屽彲涓嶅彉鐨勩?/p>
浣跨敤set涓簀ava瀛楁璁劇疆鍊鹼紝鍙互鏌ョ湅 Java Interop.
Interning
鍛藉悕絀洪棿緇存姢浜嗘瘡涓猇ar瀵硅薄鐨勫叏灞絎﹀彿鏄犲皠銆傚鏋滀嬌鐢╠ef瀹氫箟鍙橀噺娌℃湁鍦ㄥ綋鍓嶇殑鍛藉悕絀洪棿鎵懼埌璇ョ鍙鳳紝灝卞垱寤轟竴涓紝鍚﹀垯浣跨敤鐜版湁鐨勩傚垱寤烘垨鑰呭鎵劇殑榪囩▼琚О浣渋nterning銆傝繖灝辨剰鍛崇潃錛岄櫎闈濾ar瀵硅薄鍙栨秷鏄犲皠錛屽惁鍒橵ar瀵硅薄姣忔琚煡璇紝鎵浠ヨ鍦ㄥ驚鐜腑鍗冧竾涓嶈寮曠敤Var鐨勫叏灞鍙橀噺錛屽惁鍒欏皢闈炲父鎱紝閫氳繃let鎴栬卋inding璁╁叏灞鍙橀噺鍙栨秷鏄犲皠鏉ユ彁楂橀熷害銆傚懡鍚嶇┖闂村湪Evaluation涓瀯寤轟簡鍏ㄥ眬鐜錛岀紪璇戝櫒涔熸妸鎵鏈塮ree symbols褰撳仛Vars鏉ヨВ鏋愪簡銆?/p>
鍙互浣跨敤闃呰瀹?Reader)#’鏉ュ緱鍒癡ar瀵硅薄鐨勫唴閮ㄧ殑鍊箋?/p>
Non-interned鐨勭被鍨嬬殑鍙橀噺
鍙互閫氳繃with-local-vars鏉ュ垱寤簄on-interned綾誨瀷鐨勫彉閲忥紝鍦╢ree symbol瑙f瀽鐨勬椂鍊欏皢涓嶄細琚彂鐜幫紝榪欎簺鍊煎彧鑳借鎵嬪伐鐨勮闂紝浣嗘槸涔熷彲浠ョ敤浣滃綋鍓嶇嚎紼嬬殑鍙橀噺銆?/p>
user=> (defn factorial [x]
(with-local-vars [acc 1, cnt x]
(while (> @cnt 0)
(var-set acc (* @acc @cnt))
(var-set cnt (dec @cnt)))
@acc))
#'user/factorial
user=> (factorial 7)
5040
鏈夋湅鍙嬫妸Java鍜孋lojure鐨勪竴浜涗唬鐮佺墖孌墊斁鍦–lojure Google group閲屾瘮杈冿紝騫舵彁鍒癑ava鐨勬ц兘瑕佹瘮Clojure蹇お澶氫簡錛岀枒闂埌搴旵lojure鑳戒笉鑳借刀涓奐ava?
鍦ㄦ垜鐨勪竴涓紑婧愰」鐩?a >clj-starcraft涓紝鍏充簬java鐨勬ц兘闂錛屽疄闄呬笂涔熸槸鎴戝緇堥潰瀵圭殑錛屽湪鎴戝啓榪欑瘒鏂囩珷鐨勬椂錛屾垜鐨凜lojure浠g爜榪樻槸鎱簡Java浠g爜6鍊?Clojure鑺變簡70縐掕В鏋愪簡1050涓枃浠訛紝Java鍒欏彧鏈?2縐?
鐒惰岋紝70縐掑榪囧幓鐨勯熷害鑰岃█涓嶇畻澶碂緋曪紝鍦ㄥ垰寮濮嬬殑鏃跺欙紝绔熺劧鑺變簡10鍒嗛挓鏉ュ垎鏋?050涓枃浠躲傜敋鑷蟲瘮鎴戠敤Python瀹炵幇鐨勮繕瑕佹參銆?/p>
鎰熻阿Java鐨刾rofiler鍜岀儹鎯呯殑Clojure鏈嬪弸錛屼笅闈㈠垪鍑轟簡鎴戝湪鎻愬崌Clojure鎬ц兘鏂歸潰鐨勪竴浜泃ips:
(set! *warn-on-reflection* true)
榪欐亹鎬曟槸鏈閲嶈鐨勪竴涓彁鍗囷細鎵撳紑榪欎釜璁劇疆灝嗕細璀﹀憡浣犲湪浠諱綍涓澶勭敤鍒癑ava鍙嶅皠API鐨勬柟娉曞拰灞炴с傚浣犳墍鎯籌紝鐩存帴璋冪敤姘歌繙姣斿弽灝勮蹇紝涓嶇鍝噷Clojure閮戒細浣犱笉鑳借В鏋愯繖涓柟娉曪紝浣犻渶瑕佽嚜宸辯敤type hint鏂瑰紡鏉ラ伩鍏嶅弽灝勮皟鐢ㄣ傚叧浜庝嬌鐢╰ype hint錛孋lojure瀹樻柟绔欑偣緇欎簡涓涓浣曚嬌鐢ㄥ拰鎻愰熺殑渚嬪瓙銆?/p>
淇鎵鏈夊叧浜?strong>*warn-on-reflection* 鐨勭紪璇戣鍛婂悗錛屾垜鐨刢lj-starcraft浠?0鍒嗛挓闄嶅埌浜?鍒嗗崐銆?/p>
寮哄埗璁劇疆鏁版嵁綾誨瀷
Clojure鍙互浣跨敤Java鐨?a >鍩虹鏁版嵁綾誨瀷錛屾棤璁轟綍鏃跺湪寰幆鐨勬椂鍊欙紝鍧氬喅鑰冭檻灝嗕綘鐨勫煎己鍒惰漿鎹㈡垚鍩虹綾誨瀷錛岃繖灝嗗ぇ騫呮彁楂樹綘鐨勬ц兘銆傚熀紜鏁版嵁綾誨瀷鍦–lojure瀹樻柟緗戠珯鏈変緥瀛愬拰濡備綍榪涜寮哄埗杞崲鏉ユ彁楂樻ц兘銆?/p>
浣跨敤浜屽厓榪愮畻絎?/strong>
Clojure鍙互鍦ㄤ竴琛岄噷闈㈡敮鎸佸涓〃杈懼紡錛屼絾瀵逛簬榪愮畻鎿嶄綔絎︼紝鍙湁鍦ㄤ袱涓殑鏃跺欐墠琚玦nlined錛屽鏋滀綘鍙戠幇鑷繁鐨勮繍綆楃宸茬粡瓚呰繃浜嗕袱涓紝鎴栬璇ヨ冭檻閲嶅啓浣犵殑浠g爜璁╂搷浣滅鏄劇ず鐨勬垚涓轟袱涓備笅闈㈣鐪嬩袱鑰呬箣闂寸殑姣旇緝錛?/p>
user> (time (dotimes [_ 1e7] (+ 2 4 5)))
"Elapsed time: 1200.703487 msecs"
user> (time (dotimes [_ 1e7] (+ 2 (+ 4 5))))
"Elapsed time: 241.716554 msecs"
浣跨敤==浠f浛=
浣跨敤==姣旇緝鏁板瓧鏉ヤ唬鏇?錛屾彁鍗囨ц兘閭f槸鐩稿綋鏄庢樉錛?/p>
user> (time (dotimes [i 1e7] (= i i)))
"Elapsed time: 230.797482 msecs"
user> (time (dotimes [i 1e7] (== i i)))
"Elapsed time: 5.143681 msecs"
閬垮厤vectors鐨刣estructing binding
鍦ㄤ竴孌靛驚鐜錛屽鏋滀綘鎯充負浜嗘彁鍗囧彲璇繪т粠vector涓紶鍑哄鹼紝鑰冭檻涓嬫爣璁塊棶鏉ヤ唬鏇縟estructing binding銆傝櫧鐒朵唬鐮佺湅璧鋒潵鏇存竻鏅幫紝浣嗗嵈闈炲父鎱€?/p>
user> (let [v [1 2 3]]
(time
(dotimes [_ 1e7]
(let [[a b c] v]
a b c))))
"Elapsed time: 537.239895 msecs"
user> (let [v [1 2 3]]
(time
(dotimes [_ 1e7]
(let [a (v 0)
b (v 1)
c (v 2)]
a b c))))
"Elapsed time: 12.072122 msecs"
浼樺厛浣跨敤鏈湴鍙橀噺
濡傛灉浣犻渶瑕佸湪寰幆涓煡璇竴涓鹼紝浣犳垨璁擱渶瑕佽冭檻浣跨敤鏈湴鍙橀噺(閫氳繃let瀹氫箟)鏉ヤ唬鏇垮叏灞鍙橀噺銆傜湅涓嬩袱鑰呯殑鏃墮棿瀵規(guī)瘮錛?/p>
user> (time
(do
(def x 1)
(dotimes [_ 1e8]
x)))
"Elapsed time: 372.373304 msecs"
user> (time
(let [x 1]
(dotimes [_ 1e8]
x)))
"Elapsed time: 3.479041 msecs"
濡傛灉浣犳兂浣跨敤鏈湴鍙橀噺鏉ユ彁鍗囨ц兘錛屽彲浠ヨ冭檻涓嬮潰姣旇緝鍦熺殑寮忕殑鏂瑰紡鏉ラ伩鍏嶅叏灞鍙橀噺錛?/p>
(let [local-x x]
(defn my-fn [a b c]
...))
浣跨敤profiler宸ュ叿錛?/strong>
JVM鏈変袱涓猵rofiler宸ュ叿錛?-Xprof鍜?Xrunhprof錛屾壘鍒扮▼搴忕摱棰堣屼笉鏄瀻鐚溿?/p>
鏈鍚庤鏄庯細
浣犲凡緇忔敞鎰忓埌錛屽湪榪欎簺鎬ц兘鎻愬崌涓紝閫氳繃璋冪敤鐧句竾閲忕殑鎵ц鏉ユ彁鍗囦簡鍑犵櫨姣鐨勬ц兘銆傛墍浠ワ紝涓嶅埌涓囦笉寰楀凡闇瑕佹彁鍗囨ц兘鐨勬椂鍊欙紝娌″繀瑕佽浣犵殑浠g爜鐪嬭搗鏉ヤ笉澶熸竻鏅般?/p>
鍘熸枃鍦板潃: http://gnuvince.wordpress.com/2009/05/11/clojure-performance-tips/
鏈鍚庤ˉ鍏咃細鍙互閫氳繃鎸囧畾緙栬瘧涓簊tatic鏂規(guī)硶鏉ユ彁楂樻ц兘錛?br />