diff --git a/benchmark/benchmark-tests.ts b/benchmark/benchmark-tests.ts
new file mode 100644
index 000000000..363e522b0
--- /dev/null
+++ b/benchmark/benchmark-tests.ts
@@ -0,0 +1,237 @@
+///
+import Benchmark = require("benchmark");
+
+var suite = new Benchmark.Suite;
+
+// add tests
+suite.add('RegExp#test', function() {
+ /o/.test('Hello World!');
+})
+.add('String#indexOf', function() {
+ 'Hello World!'.indexOf('o') > -1;
+})
+.add('String#match', function() {
+ !!'Hello World!'.match(/o/);
+})
+// add listeners
+.on('cycle', function(event: {target: any}) {
+ console.log(String(event.target));
+})
+.on('complete', function() {
+ console.log('Fastest is ' + this.filter('fastest').pluck('name'));
+})
+// run async
+.run({ 'async': true });
+
+var fn: Function;
+var onStart: Function;
+var onCycle: Function;
+var onAbort: Function;
+var onError: Function;
+var onReset: Function;
+var onComplete: Function;
+var setup: Function;
+var teardown: Function;
+var benches: Benchmark[];
+var listener: Function;
+var count: number;
+
+// basic usage (the `new` operator is optional)
+var bench = new Benchmark(fn);
+
+// or using a name first
+var bench = new Benchmark('foo', fn);
+
+// or with options
+var bench = new Benchmark('foo', fn, {
+
+ // displayed by Benchmark#toString if `name` is not available
+ 'id': 'xyz',
+
+ // called when the benchmark starts running
+ 'onStart': onStart,
+
+ // called after each run cycle
+ 'onCycle': onCycle,
+
+ // called when aborted
+ 'onAbort': onAbort,
+
+ // called when a test errors
+ 'onError': onError,
+
+ // called when reset
+ 'onReset': onReset,
+
+ // called when the benchmark completes running
+ 'onComplete': onComplete,
+
+ // compiled/called before the test loop
+ 'setup': setup,
+
+ // compiled/called after the test loop
+ 'teardown': teardown
+});
+
+// or name and options
+var bench = new Benchmark('foo', {
+
+ // a flag to indicate the benchmark is deferred
+ 'defer': true,
+
+ // benchmark test function
+ 'fn': function(deferred: {resolve(): void}) {
+ // call resolve() when the deferred test is finished
+ deferred.resolve();
+ }
+});
+
+// or options only
+var bench = new Benchmark({
+
+ // benchmark name
+ 'name': 'foo',
+
+ // benchmark test as a string
+ 'fn': '[1,2,3,4].sort()'
+});
+
+// a test’s `this` binding is set to the benchmark instance
+var bench = new Benchmark('foo', function() {
+ 'My name is '.concat(this.name); // My name is foo
+});
+
+// get odd numbers
+Benchmark.filter([1, 2, 3, 4, 5], function(n) {
+ return n % 2;
+}); // -> [1, 3, 5];
+
+// get fastest benchmarks
+Benchmark.filter(benches, 'fastest');
+
+// get slowest benchmarks
+Benchmark.filter(benches, 'slowest');
+
+// get benchmarks that completed without erroring
+Benchmark.filter(benches, 'successful');
+
+// invoke `reset` on all benchmarks
+Benchmark.invoke(benches, 'reset');
+
+// invoke `emit` with arguments
+Benchmark.invoke(benches, 'emit', 'complete', listener);
+
+// invoke `run(true)`, treat benchmarks as a queue, and register invoke callbacks
+Benchmark.invoke(benches, {
+
+ // invoke the `run` method
+ 'name': 'run',
+
+ // pass a single argument
+ 'args': true,
+
+ // treat as queue, removing benchmarks from front of `benches` until empty
+ 'queued': true,
+
+ // called before any benchmarks have been invoked.
+ 'onStart': onStart,
+
+ // called between invoking benchmarks
+ 'onCycle': onCycle,
+
+ // called after all benchmarks have been invoked.
+ 'onComplete': onComplete
+});
+
+var element: HTMLElement;
+// basic usage
+var bench = new Benchmark({
+ 'setup': function() {
+ var c = this.count,
+ element = document.getElementById('container');
+ while (c--) {
+ element.appendChild(document.createElement('div'));
+ }
+ },
+ 'fn': function() {
+ element.removeChild(element.lastChild);
+ }
+});
+
+// or using strings
+var bench = new Benchmark({
+ 'setup': '\
+ var a = 0;\n\
+ (function() {\n\
+ (function() {\n\
+ (function() {',
+ 'fn': 'a += 1;',
+ 'teardown': '\
+ }())\n\
+ }())\n\
+ }())'
+});
+
+var bizarro = bench.clone({
+ 'name': 'doppelganger'
+});
+
+// unregister a listener for an event type
+bench.off('cycle', listener);
+
+// unregister a listener for multiple event types
+bench.off('start cycle', listener);
+
+// unregister all listeners for an event type
+bench.off('cycle');
+
+// unregister all listeners for multiple event types
+bench.off('start cycle complete');
+
+// unregister all listeners for all event types
+bench.off();
+
+// register a listener for an event type
+bench.on('cycle', listener);
+
+// register a listener for multiple event types
+bench.on('start cycle', listener);
+
+// basic usage
+bench.run();
+
+// or with options
+bench.run({ 'async': true });
+
+// basic usage
+suite.add(fn);
+
+// or using a name first
+suite.add('foo', fn);
+
+// or with options
+suite.add('foo', fn, {
+ 'onCycle': onCycle,
+ 'onComplete': onComplete
+});
+
+// or name and options
+suite.add('foo', {
+ 'fn': fn,
+ 'onCycle': onCycle,
+ 'onComplete': onComplete
+});
+
+// or options only
+suite.add({
+ 'name': 'foo',
+ 'fn': fn,
+ 'onCycle': onCycle,
+ 'onComplete': onComplete
+});
+
+// basic usage
+suite.run();
+
+// or with options
+suite.run({ 'async': true, 'queued': true });
diff --git a/benchmark/benchmark.d.ts b/benchmark/benchmark.d.ts
new file mode 100644
index 000000000..3365f335c
--- /dev/null
+++ b/benchmark/benchmark.d.ts
@@ -0,0 +1,192 @@
+// Type definitions for Benchmark v1.0.0
+// Project: http://benchmarkjs.com
+// Definitions by: Asana
+// Definitions: https://github.com/borisyankov/DefinitelyTyped
+
+declare module "benchmark" {
+ class Benchmark {
+ static deepClone(value: T): T;
+ static each(obj: Object | any[], callback: Function, thisArg?: any): void;
+ static extend(destination: Object, ...sources: Object[]): Object;
+ static filter(arr: T[], callback: (value: T) => any, thisArg?: any): T[];
+ static filter(arr: T[], filter: string, thisArg?: any): T[];
+ static forEach(arr: T[], callback: (value: T) => any, thisArg?: any): void;
+ static formatNumber(num: number): string;
+ static forOwn(obj: Object, callback: Function, thisArg?: any): void;
+ static hasKey(obj: Object, key: string): boolean;
+ static indexOf(arr: T[], value: T, fromIndex?: number): number;
+ static interpolate(template: string, values: Object): string;
+ static invoke(benches: Benchmark[], name: string | Object, ...args: any[]): any[];
+ static join(obj: Object, separator1?: string, separator2?: string): string;
+ static map(arr: T[], callback: (value: T) => K, thisArg?: any): K[];
+ static pluck(arr: T[], key: string): K[];
+ static reduce(arr: T[], callback: (accumulator: K, value: T) => K, thisArg?: any): K;
+
+ static options: Benchmark.Options;
+ static platform: Benchmark.Platform;
+ static support: Benchmark.Support;
+ static version: string;
+
+ constructor(fn: Function | string, options?: Benchmark.Options);
+ constructor(name: string, fn: Function | string, options?: Benchmark.Options);
+ constructor(name: string, options?: Benchmark.Options);
+ constructor(options: Benchmark.Options);
+
+ aborted: boolean;
+ compiled: Function | string;
+ count: number;
+ cycles: number;
+ error: Error;
+ fn: Function | string;
+ hz: number;
+ running: boolean;
+ setup: Function | string;
+ teardown: Function | string;
+
+ stats: Benchmark.Stats;
+ times: Benchmark.Times;
+
+ abort(): Benchmark;
+ clone(options: Benchmark.Options): Benchmark;
+ compare(benchmark: Benchmark): number;
+ emit(type: string | Object): any;
+ listeners(type: string): Function[];
+ off(type?: string, listener?: Function): Benchmark;
+ off(types: string[]): Benchmark;
+ on(type?: string, listener?: Function): Benchmark;
+ on(types: string[]): Benchmark;
+ reset(): Benchmark;
+ run(options?: Benchmark.Options): Benchmark;
+ toString(): string;
+ }
+
+ module Benchmark {
+ export interface Options {
+ async?: boolean;
+ defer?: boolean;
+ delay?: number;
+ id?: string;
+ initCount?: number;
+ maxTime?: number;
+ minSamples?: number;
+ minTime?: number;
+ name?: string;
+ onAbort?: Function;
+ onComplete?: Function;
+ onCycle?: Function;
+ onError?: Function;
+ onReset?: Function;
+ onStart?: Function;
+ setup?: Function | string;
+ teardown?: Function | string;
+ fn?: Function | string;
+ queued?: boolean;
+ }
+
+ export interface Platform {
+ description: string;
+ layout: string;
+ manufacturer: string;
+ name: string;
+ os: string;
+ prerelease: string;
+ product: string;
+ version: string;
+ toString(): string;
+ }
+
+ export interface Support {
+ air: boolean;
+ argumentsClass: boolean;
+ browser: boolean;
+ charByIndex: boolean;
+ charByOwnIndex: boolean;
+ decompilation: boolean;
+ descriptors: boolean;
+ getAllKeys: boolean;
+ iteratesOwnFirst: boolean;
+ java: boolean;
+ nodeClass: boolean;
+ timeout: boolean;
+ }
+
+ export interface Stats {
+ deviation: number;
+ mean: number;
+ moe: number;
+ rme: number;
+ sample: any[];
+ sem: number;
+ variance: number;
+ }
+
+ export interface Times {
+ cycle: number;
+ elapsed: number;
+ period: number;
+ timeStamp: number;
+ }
+
+ export class Deferred {
+ constructor(clone: Benchmark);
+
+ benchmark: Benchmark;
+ cycles: number;
+ elapsed: number;
+ timeStamp: number;
+ }
+
+ export class Event {
+ constructor(type: string | Object);
+
+ aborted: boolean;
+ cancelled: boolean;
+ currentTarget: Object;
+ result: any;
+ target: Object;
+ timeStamp: number;
+ type: string;
+ }
+
+ export class Suite {
+ static options: { name: string };
+
+ constructor(name?: string, options?: Options);
+
+ aborted: boolean;
+ length: number;
+ running: boolean;
+ abort(): Suite;
+ add(name: string, fn: Function | string, options?: Options): Suite;
+ add(fn: Function | string, options?: Options): Suite;
+ add(name: string, options?: Options): Suite;
+ add(options: Options): Suite;
+ clone(options: Options): Suite;
+ emit(type: string | Object): any;
+ filter(callback: Function | string): Suite;
+ forEach(callback: Function): Suite;
+ indexOf(value: any): number;
+ invoke(name: string, ...args: any[]): any[];
+ join(separator?: string): string;
+ listeners(type: string): Function[];
+ map(callback: Function): any[];
+ off(type?: string, callback?: Function): Benchmark;
+ off(types: string[]): Benchmark;
+ on(type?: string, callback?: Function): Benchmark;
+ on(types: string[]): Benchmark;
+ pluck(property: string): any[];
+ pop(): Function;
+ push(benchmark: Benchmark): number;
+ reduce(callback: Function, accumulator: T): T;
+ reset(): Suite;
+ reverse(): any[];
+ run(options?: Options): Suite;
+ shift(): Benchmark;
+ slice(start: number, end: number): any[];
+ slice(start: number, deleteCount: number, ...values: any[]): any[];
+ unshift(benchmark: Benchmark): number;
+ }
+ }
+
+ export = Benchmark;
+}