Belt Error Perf
JavaScript performance comparison
Preparation code
<script>
Benchmark.prototype.setup = function() {
/*
* belt.js
*
* A general-purpose utility function. Used to extend
* and house my general-purpose js-utils.
*
*/
(function(global) {
/*
* SETUP
*
* Initialize public and private variables, and overwrite
* the `global.BELT` namespace, caching anything that might be there.
* Orient document, navigator, location to the global object, since we're
* operating inside a self-invoking function closure.
*
* BELT : Global namespace for utility functions.
*
* _cache : A private cache object accessed by BELT fns.
* _errors : A private error queue; populated by BELT error logging.
* _belt : A copy of anything in the `global.BELT` namespace, in case
* we end up overwriting something.
* _console : A copy of the `global.console` if it exists. BELT defaults to
* creating a safe copy of console in the global namespace,
* overwriting the normal `global.console`.
*
*/
var BELT = {},
_cache = {},
_errors = [],
// Make sure document, location, navigator are properly defined
// within the scope of this self-invoking function.
document = global.document,
location = global.location,
navigator = global.navigator;
// Since we'll be overwriting global.BELT and global.console
// make the old values accessible via the _cache.
_cache.global_BELT = global.BELT;
_cache.global_console = global.console;
/* ---------------- top ----------------- */
/*
* CORE JS UTILITIES
*
* Borrow various native functions for internal use.
* Any self-rolled object and array manipulation functions go here.
*
* slice()
* Array.prototype.slice
*
* push()
* Array.prototype.push
*
* toString()
* Object.prototype.toString
*
* hasOwnProperty()
* Object.prototype.hasOwnProperty
*
* isArray()
* Checks if the thing passed in is an array.
* @arguments : something
* @return : [boolean]
*
* isObject()
* Checks if the thing passed in is an object.
* @arguments : something
* @return : [boolean]
*
* clone()
* Create a deep copy of an object via recursion.
* This is more effective than JSON.* means of cloning objects,
* since cloned functions are usable.
* This is for non-prototypal object literals and arrays, rather
* than constructed objects... for the moment.
* Currently outstrips jQuery.extend() [v 1.8.3] in performance
* by a significant margin : http://jsperf.com/belt-core-deep-clone
* @arguments : from [,to]
* @return : [clone of object]
*
* namespace()
* Return the tip of a namespace. If it doesn't exist yet, then
* create an object in this namespace.
* Using `BELT.namespace()` prevents accidental rewrites when
* working with big namespaces.
* @arguments : [string]
* @return : [Object object]
*
* inherit()
* A simple inheritance function.
* @arguments : parent, child /
* {parent:, child:}
* @return : ...
*
* extend()
* @arguments : obj, extendWithProperties
* @return : boolean
*
* createConsoleAlias()
* The JavaScript global console object is not consistently implemented
* cross brwoser yet.
* This creates a `console` object to prevent script crashes when you
* attempt to access a method of an undefined object. Methods are aliased
* in stages based on browser availability.
* As far as I know, I've grouped the commands by availability in different
* browser environments. The most generic set, `ie_opera_ff_webkit` will
* work pretty reliably x-browser when you use it.
* @arguments : none
* @return : Pseudo-console.
*
*/
(function defineCoreModule(BELT) {
BELT.core = {};
BELT.slice = BELT.core.slice = Array.prototype.slice;
BELT.push = BELT.core.push = Array.prototype.push;
BELT.toString = BELT.core.toString = Object.prototype.toString;
BELT.hasOwnProperty = BELT.core.hasOwnProperty = Object.prototype.hasOwnProperty;
BELT.isArray = BELT.core.isArray = function(it) {
return (it instanceof Array);
};
BELT.isObject = BELT.core.isObject = function(it) {
return (typeof it === 'object');
};
BELT.clone = BELT.core.clone = (function() {
// Private helper function for public clone() API.
function recurse(from_i, doppel_i) {
if (BELT.core.isArray(from_i) || BELT.core.isObject(from_i)) {
return BELT.core.clone(from_i, doppel_i);
} else {
return from_i;
}
}
return function(from, to) {
var doppel,
i;
if (BELT.core.isArray(from)) {
doppel = to || [];
for (i = 0; i < from.length; i += 1) {
doppel[i] = recurse(from[i], doppel[i]);
}
} else if (BELT.core.isObject(from)) {
doppel = to || {};
for (i in from) {
doppel[i] = recurse(from[i], doppel[i]);
}
} else {
doppel = from;
}
return doppel;
};
}());
BELT.namespace = BELT.core.namespace = function(str) {
var levels = str && str.split && str.split('.'),
i = 0,
name_space,
step,
msg;
// Fallthrough if incorrect usage.
if (levels === undefined) {
msg = 'BELT.namespace(str) : str can\'t be ' + str;
throw new Error(msg);
}
// Find the namespace (should be first str.)
name_space = levels[0];
step = global[levels[0]] || (global[levels[0]] = {});
levels.shift();
// Iterate through the levels of the namespace string.
for (; i < levels.length; i += 1) {
if (typeof step[levels[i]] === 'undefined') {
step[levels[i]] = {};
} else if (typeof step[levels[i]] === 'function') {
i += 1;
msg = 'BELT.namespace() : ' + name_space + '.';
msg += levels.slice(0, i).join('.') + ' is a function';
throw new Error(msg);
}
step = step[levels[i]];
}
return step;
};
BELT.inherit = BELT.core.inherit = function inherit(P, C) {
var opt = typeof P === 'object' ?
P :
{parent:P, child:C},
F = function() {};
F.prototype = opt.parent.prototype;
opt.child.prototype = new F();
opt.child.prototype_chain = opt.parent.prototype_chain || [];
opt.child.prototype_chain.push(opt.parent.prototype);
opt.child.prototype.constructor = opt.child;
};
// How to use to write plugins:
// BELT.extend(BELT.namespace('ns'), { props });
BELT.extend = BELT.core.extend = function(obj, extendWithProperties) {
console.error('WARNING: BELT.extend() incomplete.');
};
BELT.core.createConsoleAlias = function(){
var new_console = new function BELTConsole() {},
g_console = BELT.storage.get('global_console'),
method_groups = {
ie_opera_ff_webkit: ['log', 'warn', 'error', 'info', 'assert', 'clear'],
opera_ff_webkit: ['dir', 'trace', 'profile', 'profileEnd', 'group', 'groupEnd'],
ff_webkit: ['debug', 'groupCollapsed', 'time', 'timeEnd', 'noSuchMethod'],
webkit: ['timeStamp', 'markTimeline', 'dirxml']
},
group,
method,
fn,
i;
for (group in method_groups) {
for (i = 0; i < method_groups[group].length; i += 1) {
new_console[method_groups[group][i]] = (function(method) {
// Must be called directly on console object, otherwise you
// have IllegalInvocation errors.
if (g_console[method]) {
fn = function(a) { g_console[method](a) };
} else if (g_console['log']) {
fn = function(a) { g_console['log'](a) };
} else {
fn = function(){};
}
return fn;
}(method_groups[group][i]));
}
}
// Allow direct access to private Webkit Console APIs that aren't methods.
new_console.memory = g_console.memory || {};
new_console.profiles = g_console.profiles || {};
// Return aliased functions.
return new_console;
};
}(BELT));
/*
* PROBLEM
*
* Error handling for your JS app.
*
* reportProblem()
* Used for logging problems. ...?
* @arguments : message [, type][, fn_name]
* { message:, [,type:] [,fn_name:] }
* @return :
*
* Err
* @arguments : message [, fn_name]
* { message: [, fn_name:] }
*/
(function defineProblemModule(BELT) {
BELT.problem = {}; // namespace.
// Public API.
BELT.reportProblem = BELT.problem.report = function(message, type, fn_name) {
var opt = (typeof message === 'object') ?
message :
{message: message, type: type, fn_name: fn_name};
// Mandatory Arg: message.
opt.message === undefined &&
BELT.problem.report({ /* !!! Error message API */ });
// Processing ...
console.error('Error: BELT.problem.report() incomplete.');
};
// Constructors.
BELT.problem.Error = function(message, fn_name) {
var opt = typeof message === 'object' ?
message :
{ message: message, fn_name: fn_name };
this.type = 'Error';
this.name = this.constructor.name || 'Error';
this.message = opt.message || 'Unhelpful generic error.';
this.timestamp = BELT.date.timestamp();
this.navigator_raw = global.navigator || 'Unavailable.';
this.location_raw = global.location || 'Unavailable.';
};
BELT.core.inherit(global.Error, BELT.problem.Error);
}(BELT));
/*
* STORAGE (CACHE)
*
* storage.set()
* Set a key-value pair in the private _cache object.
* @arguments : key, value / {key:, value:}
* @returns : true if success
*
* storage.get()
* Retreive an item from the private _cache object.
* @arguments : key [string] / [empty]
* @return : _cache.key / clone of _cache
*
*/
(function defineStorageModule(BELT) {
BELT.storage = {};
BELT.storage.set = function(key, value) {
var opt = (typeof key === 'object') ?
key :
{key: key, value: value};
// Arg checking: overkill, but better than losing data.
opt.key === undefined &&
BELT.problem.report({/* !!! Error message API */});
typeof opt.key !== 'string' &&
BELT.problem.report({ /* !!! Error message API */});
opt.value === undefined &&
BELT.problem.report({ /* !!! Error message API */ });
// Set to private cache.
_cache[opt.key] = opt.value;
};
BELT.storage.get = function(key) {
if (key) { return _cache[key] }
else { return BELT.core.clone(_cache) }
};
}(BELT));
/*
* DATE
*
* General purpose date handling module.
* Among other things, it shims `Date.now()` if it is not supported by
* the browser.
* `new Date().getTime()` outperforms `+(new Date)` by a fairly large margin,
* so that's the chosen shim. http://jsperf.com/creating-timestamps
*
* timestamp()
* Returns a unix timestamp.
*
*/
(function defineDateModule(BELT) {
BELT.date = {};
// Shim for older ECMA (sub 1.5) engines.
Date.now = Date.now || function now() {return new Date().getTime() };
BELT.timestamp = BELT.date.timestamp = function() {
return Math.floor(Date.now() / 1000);
};
}(BELT));
/* ----------- bottom ------------- */
/*
* EXPOSE/EXPORT
*
* Create a safe console alias.
*
* Expose local BELT variable to the global namespace, based on the
* global variable passed into this self-invoking function.
*
*/
global.console = BELT.core.createConsoleAlias();
global.BELT = BELT;
}(window)); // Will either be GLOBAL (node) || window (browser)
};
</script>
Test runner
Warning! For accurate results, please disable Firebug before running the tests. (Why?)
Java applet disabled.
| Test | Ops/sec | |
|---|---|---|
Belt.error (no strings, no stack) |
|
pending… |
Native error |
|
pending… |
Compare results of other browsers
Revisions
You can edit these tests or add even more tests to this page by appending /edit to the URL. Here’s a list of current revisions for this page:
- Revision 1: published by John Cockrell
- Revision 2: published
- Revision 3: published by John Cockrell and last updated
- Revision 4: published by John
- Revision 5: published
0 comments