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

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

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

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

3535閲覧

変数名や関数名の長さ

退会済みユーザー

退会済みユーザー

総合スコア0

Python 3.x

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

1クリップ

投稿2019/06/09 16:09

変数名や関数名の長短によって実行速度が変わるのか疑問に思い、JupyterLabで%%timeitを使って試したところ有意な差はありませんでした。
下記コードは速さを調べたときのものです。
実行速度に差がないのはどうしてなのでしょうか?
試す前は、長いもののほうが多少なりとも遅くなるだろうと考えていたので驚いています。

また、メモリの使用量に差はあるのかも調べたいのですが、どうすればよいでしょうか?

Python

1a = [i for i in range(10 ** 6)] 2students_list_of_fdafagdafdagadgragdhfedagrdas = [i for i in range(10 ** 6)] 3 4def b(x, y): 5 return x + y 6 7def aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(x, y): 8 return x + y 9 10 11%%timeit 12for i in a: 13 i 14> 11.4 ms ± 537 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 15 16%%timeit 17for i in students_list_of_fdafagdafdagadgragdhfedagrdas: 18 i 19> 11.2 ms ± 228 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 20 21%%timeit 22for i in range(10 ** 6): 23 b(i, i + 1) 24> 155 ms ± 2.67 ms per loop (mean ± std. dev. of 7 runs, 10 loops each) 25 26%%timeit 27for i in range(10 ** 6): 28 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(i, i + 1) 29> 158 ms ± 7.97 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) 30

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

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

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

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

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

guest

回答2

0

ベストアンサー

Pythonのグローバル変数は実質的にdictのアクセスと同程度のスピードと考えられます。ちょっと測定してみますと・・・

python

1from time import perf_counter_ns 2 3 4def lookup(d, vn): 5 for _ in range(1000): 6 d[vn] = 1 7 8def elapsed(vn): 9 d = dict() 10 d[vn] = 0 # (A) 11 # d[vn[:1] + vn[1:]] = 0 # (B) 12 t1 = perf_counter_ns() 13 lookup(d, vn) 14 t2 = perf_counter_ns() 15 print(f"var name length={len(vn):4d} {t2 - t1:9,.0f}") 16 17 18elapsed('a') 19elapsed('a'*1000)

sh

1$ python3 t.py 2var name length= 1 35,700 3var name length=1000 34,400

とまぁ、誤差の程度です。しかし(A)の行をコメントアウトし、(B)のコメントを外して測定してみますと・・・

sh

1$ python3 t.py 2var name length= 1 35,700 3var name length=1000 107,600

この違いの理由を推測するに・・・

str(変数名)をdictから探す際にはまずstrのハッシュコードを計算します。strのハッシュコードは全ての文字(かな?)についてある計算をして求めるので文字列長が長ければ長いほど計算量が増えると考えられますが、strのハッシュコードは一々計算するまでもなくstrインスタンスの属性として記録されるようになっているため事実上文字列長の如何には左右されず一瞬で求まります。

さて次にハッシュコードに対応するハッシュテーブル内の位置からキーであるstrを探します。このとき文字列同士の比較が行われるはず・・・なのですが、上記の結果からdictからのlookup時間は(A)では文字列長に左右されず(B)とすると文字列長に左右されることが観察できます。

多分str同士を比較する際に、一つ一つ文字を比較するより前に「同一の実体かどうか」つまりis演算子で最初に一致を見ているのだと思います。

(A)のように登録の際のキーと参照の際のキーが同一のstrインスタンスだとstrの要素の文字を一々比較することなく一瞬で一致することがわかり、(B)のように登録の際のキーと参照の際のキーが同一でないstrインスタンスだと要素の文字を一々比較するため検索時間が文字列長に比例した時間がかかってくるのだと思います。

さて、Pythonはモジュールをコンパイルする際に同一の変数名の検索用のstrは少なくともモジュール内で全て同一のインスタンスでアクセスするようにしているだろうと思います。

以上から変数名の長さはアクセス時間に影響しないと考えられます。(推測こみで)


Pythonに限らず文字列の一致の際にインスタンスの同一性をチェックしたり、ソースコードをコンパイルする際に識別子や文字列リテラルを同一のインスタンスにするような最適化はあたりまえのように行われる一般的なものと思います。

変数名の長さによってスピードが変わるといったような話は原始的なつくりのインタープリタではあったかも知れませんが、昨今の普通の言語システムでは「そういうことはほぼないようにうまいこと実装されている」と考えてよいのではないでしょうか。


追記:
Pythonのようなインタープリタ言語ではインタープリタの内部情報を動的にアクセスできる仕組みが備わっています。例えばモジュールのトップレベルの属性(変数や関数やクラス)は

名前

でアクセスする他に

globals()['名前']

でもアクセスできますが、後者のようなことを必要もないのにやってしまうと分かり易さを損なうという以外に速度的なペナルティーの可能性も意識しておいた方がよいかも知れません。

投稿2019/06/09 17:57

編集2019/06/09 18:06
KSwordOfHaste

総合スコア18394

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

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

退会済みユーザー

退会済みユーザー

2019/06/09 21:02

こんなアプローチから考察ができるとは思いもよりませんでした。 推測を含むとはいえ、有益な情報をくださってありがとうございます。
KSwordOfHaste

2019/06/10 02:04

同一インスタンスのキーによるアクセスが頻繁に行われことを考えると、回答に書いたような工夫は計算量をO(N)からO(1)に短縮できるという意味で必然に近いと思います。等値比較やハッシュ法などの基本アルゴリズムはライブラリーで提供されているため自分で実装する機会は少ないですが、それらが用いている基本テクニックをよく知っておくことはライブラリーを最適に使うために重要な知識であると自分は思います。質問者さんがやっておられるような実験も言語やライブラリーの特徴を把握する上で大切な「学びの手段」だと思います!
guest

0

コンピューターは充分に高速ですから、この程度で目に見えるほどの差が観測されることはまず考えられません。また、変数名を数十文字増やしたことで圧迫されるほどの極少メモリで動いている環境などありません。拘るだけ時間の無駄だと思います。

投稿2019/06/09 16:37

KojiDoi

総合スコア13671

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問