function numel( x ) {
	var ndims;
	var sh;
	var n;
	var d;
	var i;

	// Note: we intentionally avoid rigorous ndarray checks to minimize performance impacts. This obviously means that non-ndarray-like objects (e.g., vanilla arrays) can sneak through, but this is likely all right for the purposes of this function...
	if ( typeof x !== 'object' || x === null ) {
		throw new TypeError( format( 'invalid argument. Must provide an ndarray. Value: `%s`.', x ) );
	}
	n = x.length;
	if ( isNonNegativeInteger( n ) ) {
		return n;
	}
	sh = x.shape;
	if ( !isCollection( sh ) ) {
		throw new TypeError( format( 'invalid argument. Must provide an ndarray. Value: `%s`.', x ) );
	}
	ndims = sh.length;
	if ( ndims === 0 ) {
		// Note: for minimal "ndarray-like objects", this will erroneously return zero when `x` is a zero-dimensional ndarray. This is part of the rationale for having a `length` property on actual ndarrays. As we don't can't know whether a provided ndarray-like is actually zero-dimensional without knowing/inspecting implementation details, we return zero here...
		return 0;
	}
	n = 1;
	for ( i = 0; i < ndims; i++ ) {
		d = sh[ i ];
		if ( !isNonNegativeInteger( d ) ) {
			throw new TypeError( format( 'invalid argument. Must provide an ndarray. Value: `%s`.', x ) );
		}
		n *= d;
	}
	return n;
}
Returns the number of elements in an ndarray.

@param {ndarrayLike} x - input ndarray
@throws {TypeError} must provide an ndarray
@returns {NonNegativeInteger} number of elements

@example
var zeros = require( '@stdlib/ndarray/zeros' );

var n = numel( zeros( [ 3, 3, 3 ] ) );
// returns 27