function Benchmark( name, opts, benchmark ) {
	var hasTicked;
	var hasTocked;
	var self;
	var time;
	if ( !( this instanceof Benchmark ) ) {
		return new Benchmark( name, opts, benchmark );
	}
	self = this;
	hasTicked = false;
	hasTocked = false;

	EventEmitter.call( this );

	// Private properties:
	setReadOnly( this, '_benchmark', benchmark );
	setReadOnly( this, '_skip', opts.skip );

	defineProperty( this, '_ended', {
		'configurable': false,
		'enumerable': false,
		'writable': true,
		'value': false
	});

	defineProperty( this, '_running', {
		'configurable': false,
		'enumerable': false,
		'writable': true,
		'value': false
	});

	defineProperty( this, '_exited', {
		'configurable': false,
		'enumerable': false,
		'writable': true,
		'value': false
	});

	defineProperty( this, '_count', {
		'configurable': false,
		'enumerable': false,
		'writable': true,
		'value': 0
	});

	// Read-only:
	setReadOnly( this, 'name', name );
	setReadOnly( this, 'tic', start );
	setReadOnly( this, 'toc', stop );
	setReadOnly( this, 'iterations', opts.iterations );
	setReadOnly( this, 'timeout', opts.timeout );

	return this;

	/**
	* Starts a benchmark timer.
	*
	* ## Notes
	*
	* -   Using a scoped variable prevents nefarious mutation by bad actors hoping to manipulate benchmark results.
	* -   The one attack vector which remains is manipulation of the `require` cache for `tic` and `toc`.
	* -   One way to combat cache manipulation is by comparing the checksum of `Function#toString()` against known values.
	*
	* @private
	*/
	function start() {
		if ( hasTicked ) {
			self.fail( '.tic() called more than once' );
		} else {
			self.emit( 'tic' );
			hasTicked = true;
			time = tic();
		}
	}

	/**
	* Stops a benchmark timer.
	*
	* @private
	* @returns {void}
	*/
	function stop() {
		var elapsed;
		var secs;
		var rate;
		var out;

		if ( hasTicked === false ) {
			return self.fail( '.toc() called before .tic()' );
		}
		elapsed = toc( time );
		if ( hasTocked ) {
			return self.fail( '.toc() called more than once' );
		}
		hasTocked = true;
		self.emit( 'toc' );

		secs = elapsed[ 0 ] + ( elapsed[ 1 ]/1e9 );
		rate = self.iterations / secs;

		out = {
			'ok': true,
			'operator': 'result',
			'iterations': self.iterations,
			'elapsed': secs,
			'rate': rate
		};
		self.emit( 'result', out );
	}
}
Benchmark constructor.

@constructor
@param {string} name - benchmark name
@param {Options} opts - benchmark options
@param {boolean} opts.skip - boolean indicating whether to skip a benchmark
@param {PositiveInteger} opts.iterations - number of iterations
@param {PositiveInteger} opts.timeout - number of milliseconds before a benchmark automatically fails
@param {Function} [benchmark] - function containing benchmark code
@returns {Benchmark} Benchmark instance

@example
var bench = new Benchmark( 'beep', function benchmark( b ) {
    var x;
    var i;
    b.comment( 'Running benchmarks...' );
    b.tic();
    for ( i = 0; i < b.iterations; i++ ) {
        x = Math.sin( Math.random() );
        if ( x !== x ) {
            b.ok( false, 'should not return NaN' );
        }
    }
    b.toc();
    if ( x !== x ) {
        b.ok( false, 'should not return NaN' );
    }
    b.comment( 'Finished running benchmarks.' );
    b.end();
});