Created
August 12, 2012 22:56
-
-
Save lynaghk/3335154 to your computer and use it in GitHub Desktop.
content-based pubsub via core.match. Faster than I expected!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns crossfilter.busses | |
(:use-macros [c2.util :only [p pp]] | |
[clojure.core.match.js :only [match]] | |
[crossfilter.macros :only [subscribe!]]) | |
(:require [clojure.string :as str] | |
[goog.pubsub.PubSub :as goog.pubsub.PubSub] | |
[goog.object :as gobj])) | |
(set! *print-fn* #(.log js/console %)) | |
(def n "Number of messages" 100000) | |
(def m "Number of subscribers" 20) | |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
;;Hand-rolled regex-based pubsub | |
(let [!subscribers (js-obj) | |
publish! (fn [topic & args] | |
(gobj/forEach !subscribers | |
(fn [re fs] | |
(when (.match topic re) | |
(.forEach fs #(apply % args)))))) | |
subscribe! (fn [topic f] | |
(let [topic-re (re-pattern (str "^" (-> topic | |
(str/replace "*" "[^/]*")) | |
"$"))] | |
(aset !subscribers | |
topic-re | |
(let [a (or (aget !subscribers topic-re) | |
(array))] | |
(.push a f) | |
a))))] | |
(dotimes [_ m] | |
(subscribe! "my-topic" (fn []))) | |
(print "approx pubsub") | |
(time | |
(dotimes [i n] | |
(publish! "my-topic")))) | |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
;;Google Closure's exact string pubsub | |
(let [chan (goog.pubsub.PubSub.)] | |
(dotimes [_ m] | |
(.subscribe chan "my-topic" (fn []))) | |
(print "goog.pubsub") | |
(time | |
(dotimes [i n] | |
(.publish chan "my-topic")))) | |
;;;;;;;;;;;;;;;;;;;;;;;;;; | |
;;Core.match-based pubsub | |
(def *!subscribers* (atom [])) | |
(defn publish! [m] | |
(doseq [s @*!subscribers*] | |
(s m))) | |
;; Tested in CLJS; this macro defined in a CLJ file. | |
;; | |
;; (defmacro subscribe! [pattern & body] | |
;; `(swap! ~'*!subscribers* conj | |
;; (fn [m#] | |
;; (match [m#] | |
;; [~pattern] (do ~@body))))) | |
(do (print "match pubsub with string matching") | |
(dotimes [_ m] | |
(subscribe! "my-topic" | |
"no-op")) | |
(time | |
(dotimes [i n] | |
(publish! "my-topic")))) | |
(reset! *!subscribers* []) | |
(do (print "match pubsub with map destructuring") | |
(dotimes [_ m] | |
(subscribe! {:with x} | |
"no-op")) | |
(time | |
(dotimes [i n] | |
(publish! {:with "destructuring"})))) | |
;;Results from a MacBook Air, Closure advanced mode compilations. | |
;; approx pubsub | |
;; "Elapsed time: 16686 msecs" | |
;; goog.pubsub | |
;; "Elapsed time: 1417 msecs" | |
;; match pubsub with string matching | |
;; "Elapsed time: 583 msecs" | |
;; match pubsub with map destructuring | |
;; "Elapsed time: 787 msecs" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Patched; awaiting merge into master: https://github.com/lynaghk/core.match/tree/issue-52