If as the input you provide the (integer) power, what is the fastest way to create the corresponding power of ten? Here are four alternatives I could come up with, and the fastest way seems to be using an f-string:

```
from functools import partial
from time import time
import numpy as np
def fstring(power):
return float(f'1e{power}')
def asterisk(power):
return 10**power
methods = {
'fstring': fstring,
'asterisk': asterisk,
'pow': partial(pow, 10),
'np.pow': partial(np.power, 10, dtype=float)
}
# "dtype=float" is necessary because otherwise it will raise:
# ValueError: Integers to negative integer powers are not allowed.
# see https://stackoverflow.com/a/43287598/5472354
powers = [int(i) for i in np.arange(-10000, 10000)]
for name, method in methods.items():
start = time()
for i in powers:
method(i)
print(f'{name}: {time() - start}')
```

Results:

```
fstring: 0.008975982666015625
asterisk: 0.5190775394439697
pow: 0.4863283634185791
np.pow: 0.046906232833862305
```

I guess the f-string approach is the fastest because nothing is actually calculated, though it only works for integer powers of ten, whereas the other methods are more complicated operations that also work with any real number as the base and power. So is the f-string actually the best way to go about it?

·
Santiago Trujillo

You're comparing apples to oranges here. `10 ** n`

computes an integer (when `n`

is non-negative), whereas `float(f'1e{n}')`

computes a floating-point number. Those won't take the same amount of time, but they solve different problems so it doesn't matter which one is faster.

But it's worse than that, because there is the overhead of calling a function, which is included in your timing for all of your alternatives, but only *some* of them actually involve calling a function. If you write `10 ** n`

then you aren't calling a function, but if you use `partial(pow, 10)`

then you *have* to call it as a function to get a result. So you're not actually comparing the speed of `10 ** n`

fairly.

Instead of rolling your own timing code, use the `timeit`

library, which is designed for doing this properly. The results are in seconds for 1,000,000 repetitions (by default), or equivalently they are the average time in microseconds for one repetiton.

Here's a comparison for computing integer powers of 10:

```
>>> from timeit import timeit
>>> timeit('10 ** n', setup='n = 500')
1.09881673199925
>>> timeit('pow(10, n)', setup='n = 500')
1.1821871869997267
>>> timeit('f(n)', setup='n = 500; from functools import partial; f = partial(pow, 10)')
1.1401332350014854
```

And here's a comparison for computing floating-point powers of 10: note that computing `10.0 ** 500`

or `1e500`

is pointless because the result is simply an `OverflowError`

or `inf`

.

```
>>> timeit('10.0 ** n', setup='n = 200')
0.12391662099980749
>>> timeit('pow(10.0, n)', setup='n = 200')
0.17336435099969094
>>> timeit('f(n)', setup='n = 200; from functools import partial; f = partial(pow, 10.0)')
0.18887039500077663
>>> timeit('float(f"1e{n}")', setup='n = 200')
0.44305286100097874
>>> timeit('np.power(10.0, n, dtype=float)', setup='n = 200; import numpy as np')
1.491982370000187
>>> timeit('f(n)', setup='n = 200; from functools import partial; import numpy as np; f = partial(np.power, 10.0, dtype=float)')
1.6273324920002779
```

So the fastest of these options in both cases is the obvious one: `10 ** n`

for integers and `10.0 ** n`

for floats.

·
Santiago Trujillo
Report

Another contender for the floats case, precompute all possible nonzero finite results and look them up:

```
0.0 if n < -323 else f[n] if n < 309 else inf
```

The preparation:

```
f = [10.0 ** i for i in [*range(309), *range(-323, 0)]]
inf = float('inf')
```

Benchmark with kaya3's exponent `n = 200`

as well as `n = -200`

as negative exponent with nonzero result and `n = -5000`

/ `n = 5000`

as medium-size negative/positive exponents from your original range:

```
n = 200
487 ns 487 ns 488 ns float(f'1e{n}')
108 ns 108 ns 108 ns 10.0 ** n
128 ns 129 ns 130 ns 10.0 ** n if n < 309 else inf
72 ns 73 ns 73 ns 0.0 if n < -323 else f[n] if n < 309 else inf
n = -200
542 ns 544 ns 545 ns float(f'1e{n}')
109 ns 109 ns 110 ns 10.0 ** n
130 ns 130 ns 131 ns 10.0 ** n if n < 309 else inf
76 ns 76 ns 76 ns 0.0 if n < -323 else f[n] if n < 309 else inf
n = -5000
291 ns 291 ns 291 ns float(f'1e{n}')
99 ns 99 ns 100 ns 10.0 ** n
119 ns 120 ns 120 ns 10.0 ** n if n < 309 else inf
34 ns 34 ns 34 ns 0.0 if n < -323 else f[n] if n < 309 else inf
n = 5000
292 ns 293 ns 293 ns float(f'1e{n}')
error error error 10.0 ** n
33 ns 33 ns 33 ns 10.0 ** n if n < 309 else inf
53 ns 53 ns 53 ns 0.0 if n < -323 else f[n] if n < 309 else inf
```

Benchmark code (Try it online!):

```
from timeit import repeat
solutions = [
"float(f'1e{n}')",
'10.0 ** n',
'10.0 ** n if n < 309 else inf',
'0.0 if n < -323 else f[n] if n < 309 else inf',
]
for n in 200, -200, -5000, 5000:
print(f'{n = }')
setup = f'''
n = {n}
f = [10.0 ** i for i in [*range(309), *range(-323, 0)]]
inf = float('inf')
'''
for solution in solutions:
try:
ts = sorted(repeat(solution, setup))[:3]
except OverflowError:
ts = [None] * 3
print(*('%3d ns ' % (t * 1e3) if t else ' error ' for t in ts), solution)
print()
```

·
Santiago Trujillo
Report

You could try it with a logarithmic approach using math.log and math.exp but the range of values will be limited (which you can handle with try/except).

This seems to be just as fast as fstring if not a bit faster.

```
import math
ln10 = math.log(10)
def mPow(power):
try:
return math.exp(ln10*power)
except:
return 0 if power<0 else math.inf
```

**[EDIT]** Given that we are constrained by the capabilities of floats, we might as well just prepare a list with the 617 possible powers of 10 (that can be held in a float) and get the answer by index:

```
import math
minP10,maxP10 = -308,308
powersOf10 = [10**i for i in range(maxP10+1)]+[10**i for i in range(minP10,0)]
def tenPower(power):
if power < minP10: return 0
if power > maxP10: return math.inf
return powersOf10[power] # negative indexes for powers -308...-1
```

*This one is definitely faster than fstring*

·
Santiago Trujillo
Report