Pub/Sub implementations (v17)

Revision 17 of this benchmark created by Daniel on


Description

added test with setTimeout( for publish and unsubscribe.

Preparation HTML

<script src="//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script>
  /*    
  
        jQuery pub/sub plugin by Peter Higgins (dante@dojotoolkit.org)
  
        Loosely based on Dojo publish/subscribe API, limited in scope. Rewritten blindly.
  
        Original is (c) Dojo Foundation 2004-2010. Released under either AFL or new BSD, see:
        http://dojofoundation.org/license for more information.
  
  */
  (function($) {
   var topics = {};
  
   $.publish1 = function(topic, args) {
    if (topics[topic]) {
     var currentTopic = topics[topic],
     args = args || {};
  
     for (var i = 0, j = currentTopic.length; i < j; i++) {
      currentTopic[i].call($, args);
     }
    }
   };
  
   $.subscribe1 = function(topic, callback) {
    if (!topics[topic]) {
     topics[topic] = [];
    }
  
    topics[topic].push(callback);
  
    return {
     "topic": topic,
     "callback": callback
    };
   };
  
   $.unsubscribe1 = function(handle) {
    var topic = handle.topic;
  
    if (topics[topic]) {
     var currentTopic = topics[topic];
  
     for (var i = 0, j = currentTopic.length; i < j; i++) {
      if (currentTopic[i] === handle.callback) {
       currentTopic.splice(i, 1);
      }
     }
    }
   };
  
  })(jQuery);

    // same as above but with call pushed into setTimeout(.., 0)
    
  (function($) {
   var topics = {};
  
   $.publish1threaded = function(topic, args) {
    if (topics[topic]) {
     setTimeout( function(){
     var currentTopic = topics[topic]
     , args = args || {}
  
     for (var i = 0, j = currentTopic.length; i < j; i++) {
      currentTopic[i].call($, args);
     }
     }, 0)
     

    }
   };
  
   $.subscribe1threaded = function(topic, callback) {
    if (!topics[topic]) {
     topics[topic] = [];
    }
  
    topics[topic].push(callback);
  
    return {
     "topic": topic,
     "callback": callback
    };
   };
  
   $.unsubscribe1threaded = function(handle) {
    var topic = handle.topic;
  
    if (topics[topic]) {
     setTimeout(function(){
     var currentTopic = topics[topic];
  
     for (var i = 0, j = currentTopic.length; i < j; i++) {
      if (currentTopic[i] === handle.callback) {
       currentTopic.splice(i, 1);
      }
     }
     }, 0) // end of setTimeout
    }
   };
  
  })(jQuery);

  
  /*!
   * jQuery Tiny Pub/Sub - v0.3pre - 11/4/2010
   * http://benalman.com/
   * 
   * Copyright (c) 2010 "Cowboy" Ben Alman
   * Dual licensed under the MIT and GPL licenses.
   * http://benalman.com/about/license/
   */
  /*!
   * jQuery Tiny Pub/Sub - v0.X - 11/18/2010
   * http://benalman.com/
   * 
   * Original Copyright (c) 2010 "Cowboy" Ben Alman
   * Dual licensed under the MIT and GPL licenses.
   * http://benalman.com/about/license/
   *
   * Made awesome by Rick Waldron
   *
   */
  (function(jQuery) {
   var o = jQuery({});
   jQuery.each({
    "subscribe2": "bind",
    "unsubscribe2": "unbind",
    "publish2": "trigger"
   }, function(fn, api) {
    jQuery[fn] = function() {
     o[api].apply(o, arguments);
    };
   });
  })(jQuery);

/**
*jQuery document element
*/
  (function(jQuery) {
   var o = jQuery(document);
   jQuery.each({
    "subscribe25": "bind",
    "unsubscribe25": "unbind",
    "publish25": "trigger"
   }, function(fn, api) {
    jQuery[fn] = function() {
     o[api].apply(o, arguments);
    };
   });
  })(jQuery);

  
// http://addyosmani.com/resources/essentialjsdesignpatterns/book/
(function (q) {

    var topics = {},
        subUid = -1;

    q.publishAO = function (topic, args) {

        if (!topics[topic]) {
            return false;
        }

        setTimeout(function () {
            var subscribers = topics[topic],
                len = subscribers ? subscribers.length : 0;

            while (len--) {
                subscribers[len].func(topic, args);
            }
        }, 0);

        return true;

    };

    q.subscribeAO = function (topic, func) {

        if (!topics[topic]) {
            topics[topic] = [];
        }

        var token = (++subUid).toString();
        topics[topic].push({
            token: token,
            func: func
        });
        return token;
    };

    q.unsubscribeAO = function (token) {
        for (var m in topics) {
            if (topics[m]) {
                for (var i = 0, j = topics[m].length; i < j; i++) {
                    if (topics[m][i].token === token) {
                        topics[m].splice(i, 1);
                        return token;
                    }
                }
            }
        }
        return false;
    };
}(jQuery));

/*
        var testSubscription = pubsubz.subscribe( 'example1', testSubscriber );

        pubsubz.publish( 'example1', 'hello world!' );
        pubsubz.publish( 'example1', ['test','a','b','c'] );
        pubsubz.publish( 'example1', [{'color':'blue'},{'text':'hello'}] );

        setTimeout(function(){
            pubsubz.unsubscribe( testSubscription );
        }, 0);
        
        pubsubz.publish( 'example1', 'hello again!' );
*/

</script>

Test runner

Ready to run.

Testing in
TestOps/sec
Object cache
var handle = $.subscribe1('foo', function() {
 1 + 1;
});

$.publish1('foo', {foo:'bar'});

$.unsubscribe1(handle);
ready
Object cache + threads
var handle = $.subscribe1threaded('foo', function() {
 1 + 1;
});

$.publish1threaded('foo', {foo:'bar'});

$.unsubscribe1threaded(handle);
ready
jQuery object element
$.subscribe2('foo', function() {
 1 + 1;
});

$.publish2('foo', {foo:'bar'});

$.unsubscribe2('foo');
ready

Revisions

You can edit these tests or add more tests to this page by appending /edit to the URL.