質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

キャッシュ

キャッシュはドキュメントやデータを一時的に保管するもので、アクセス処理時間を短くするために使用されます。

意見交換

クローズ

7回答

494閲覧

lru_cacheで挙動が変化するプログラム

bookyomu

総合スコア0

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

キャッシュ

キャッシュはドキュメントやデータを一時的に保管するもので、アクセス処理時間を短くするために使用されます。

0グッド

0クリップ

投稿2023/07/06 12:51

0

0

Python3

1import functools 2import sys 3 4sys.setrecursionlimit(2000) 5 6x = 0 7 8# @functools.lru_cache(maxsize=None) 9def fib(n): 10 global x 11 x += 1 12 if n < 2: 13 return n 14 return fib(n-1) + fib(n-2) 15 16def main(): 17 print(fib(20)) 18 print(x) 19 20if __name__ == "__main__": 21 main()

# @functools.lru_cache(maxsize=None)のコメントを外すと、xの値が非常に小さくなります。
lru_cacheで予期しない挙動の変化がある例は他にありますか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

回答7

#1

ikedas

総合スコア4352

投稿2023/07/06 22:18

xfib()が呼び出された回数を示すと思います。lru_cacheデコレータを有効にするとfib(20)からfib(0)までが1回ずつ呼び出されてキャッシュされるため、それ以上呼び出されません。

「予期しない」挙動の変化が起きているようには見えません。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

#2

quickquip

総合スコア11051

投稿2023/07/07 06:31

xの値を小さくしたい=呼び出し回数を減らしたい というのがlru_cacheの目的ではないでしょうか。

「主目的を達している」状態を「予期しない」と呼んでいるのはなぜか。
「予期しない」という言葉をどういう意味で使っているのか。
といったあたりの補足が必要だと思います。(そうでないと意見交換の足下があやふやです)

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

#3

bookyomu

総合スコア0

投稿2023/07/07 06:40

私が掲載したプログラムは単純なので、xfibの呼び出し回数であることは容易に分かります。
しかし、私の質問の意図は、より複雑かつlru_cacheで高速化が期待できるプログラムで、さらにlru_cacheを用いることで異なる (そして好ましくない) 挙動になるようなものはあるか、ということです。さらに、そのような挙動の変化がすぐには分からない場合もあるか知りたいです。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

#4

quickquip

総合スコア11051

投稿2023/07/07 06:49

編集2023/07/07 06:50

https://docs.python.org/ja/3/library/functools.html#functools.lru_cache

一般的には、 LRU キャッシュは前回計算した値を再利用したいときにのみ使うべきです。 そのため、副作用のある関数、呼び出すごとに個別の可変なオブジェクトを作成する必要がある関数、 time() や random() のような純粋でない関数をキャッシュする意味はありません。

これでは足りませんか?
質問のケースは「副作用のある関数」に他ならないかと思いました。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

#5

bookyomu

総合スコア0

投稿2023/07/07 06:53

なるほど。
そもそも副作用が発生する関数には適していない、という認識でよいですか?

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

#6

ikedas

総合スコア4352

投稿2023/07/07 07:53

ちょっと意地悪ないいかたになりますけど、副作用のある関数に「適していない」かどうかはそのプログラムでなにを実現したいかによるのではないでしょうか。

@quickquipさんが引用しておられるドキュメントでは、次のようにも述べられています。

関数をメモ化用の呼び出し可能オブジェクトでラップし、最近の呼び出し最大 maxsize 回まで保存するするデコレータです。高価な関数や I/O に束縛されている関数を定期的に同じ引数で呼び出すときに、時間を節約できます。

「I/Oに束縛されている」というのは外部に対する入出力処理が行われているという意味ですから、副作用にほかなりません。たとえば、適切な例かどうかわかりませんが、「同じ内容のデバッグログが大量に出力されてパフォーマンスが低下してしまうとき」というのを思いつきました。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

#7

bookyomu

総合スコア0

投稿2023/07/07 07:59

たしかにその通りですね。
回答ありがとうございました。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

最新の回答から1ヶ月経過したため この意見交換はクローズされました

意見をやりとりしたい話題がある場合は質問してみましょう!

質問する

関連した質問