def METHOD_NAME(func, target_time):
    '''Find optimal number of iterations to run func closely >= target_time.
    '''
    iters = 1
    target_time = float(target_time)
    max_iters = int(getattr(func, '_benchmark_max_iters', 0))
    # TODO automatically detect non-linear time growth
    scale_factor = getattr(func, '_benchmark_scale_factor', 0.0)
    for _ in range(10):
        if max_iters and iters > max_iters:
            return max_iters
        # print('try iters={iters}'.format(**locals()))
        t = _run_timeit(func, number=iters)
        # print('... t={t}'.format(**locals()))
        if t >= target_time:
            return iters
        if scale_factor:
            iters *= scale_factor
            continue
        # following assumes and works well for linear complexity target functions
        if t < (target_time / 2):
            # roughly target half optimal time, ensure iterations keep increasing
            iters = iters * (target_time / t / 2) + 1
            # round up to nearest power of 10
            iters = int(10 ** math.ceil(math.log10(iters)))
        elif t < target_time:
            # half/double dance is less prone to overshooting iterations
            iters *= 2
    raise Exception('could not find optimal iterations for time={} func={}'.format(target_time, repr(func)))