FizzBu??zz 問題:給定一個自然數N >= 0,列印一個數字序列,用單詞0 - N替換每個可被單詞整除的數字、被單詞整除的每個數字,以及被單詞和兩者都可整除的每個數字。3fizz5buzz35fizzbuzz

Numpy 在這方面并不出色(它不能為字串提供太多加速),但我認為它不應該太可怕,如果使用得當,它也許可以擊敗普通的 python。然而,令我驚訝的是,天真的實作的情況恰恰相反。為什么會這樣,以及如何改進這一點?
這是我用來生成計時的代碼。它包括一個純 python 參考實作、一個樸素的 numpy 實作和一個numba.jit變體,因為我認為它可以作為一個合理的性能下限。
import numpy as np
import matplotlib.pyplot as plt
import numba as nb
import timeit
def classic_fizzbuzz(N: int) -> str:
result = list()
for idx in range(N):
if idx % 3 == 0 and idx % 5 == 0:
result.append("fizzbuzz")
elif idx % 5 == 0:
result.append("buzz")
elif idx % 3 == 0:
result.append("fizz")
else:
result.append(str(idx))
return " ".join(result)
def numpy_fizzbuzz(N: int) -> str:
integers = np.arange(N)
result = np.arange(N).astype(str)
result = np.where(integers % 3 == 0, "fizz", result)
result = np.where(integers % 5 == 0, "buzz", result)
result = np.where(integers % 15 == 0, "fizzbuzz", result)
return " ".join(result)
@nb.jit(nopython=True)
def numba_fizzbuzz(N:int) -> str:
result = list()
for idx in range(N):
if idx % 3 == 0 and idx % 5 == 0:
result.append("fizzbuzz")
elif idx % 5 == 0:
result.append("buzz")
elif idx % 3 == 0:
result.append("fizz")
else:
result.append(str(idx))
return " ".join(result)
# do not measure initial compile time
numba_fizzbuzz(20)
def time_fizzbuzz(fn):
repeats = 100
times = list()
N_values = np.linspace(0, int(1e4), 100, dtype=int)
for idx in N_values:
N = int(idx)
times.append(timeit.timeit(lambda: fn(N), number=repeats) / repeats)
return N_values, times
fig, ax = plt.subplots(dpi=150) # web-quality
contendants = {
"classic": classic_fizzbuzz,
"numpy": numpy_fizzbuzz,
"numba": numba_fizzbuzz
}
for fn in contendants.values():
ax.plot(*time_fizzbuzz(fn))
ax.set_ylabel("Average Time (s)")
ax.set_label("Input")
fig.suptitle(
"Comparison of FizzBuzz implementations in Python.",
# fontsize="medium",
)
ax.set_title("Timings for various input N (averaged over 100 runs each)", fontsize="small")
ax.legend(
contendants.keys(),
loc="center left",
bbox_to_anchor=(1, 0.5),
title="Contestants",
)
fig.tight_layout()
fig.savefig("timings.png")
uj5u.com熱心網友回復:
發生這種情況的原因是您使用 numpy 方法將所有元素迭代了 3 次。您必須檢查每個呼叫的整個陣列。np.wherepython 實作只迭代陣列一次。正如您所展示的,這會更快,盡管迭代的各個步驟可能會更慢。話雖如此,您可以(ab)使用np.vectorize此應用程式,盡管它明確不是為了提高性能。在這方面,
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/464443.html
