のんびりしているエンジニアの日記

ソフトウェアなどのエンジニア的な何かを書きます。

Pythonで使うrangeとxrangeについて

Sponsored Links

皆さんこんにちは
お元気ですか。私は元気です。

さて、今日はrangeとxrangeについて見てみましょう。
さて、Pythonを使う人であれば、この2つよく使いますよね
Pythonでよく見るコードはこちらです。

for i in xrange(100):
    print i

もちろんrangeで書く人もいると思います。なんとなーくxrangeの方がいいよと言われていたり、よくわかりません。
正直、私はこの2つ何が違うのかよくわかっておりません。そこで調べてみたいなと思い、この記事を記載しています。。

まずは、コンソール上から実行してみましょう

>>> xrange(10)
xrange(10)
>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

xrangeはよくわからない結果ですが、rangeではリストを返すようですね。

この関数は range() に非常によく似ていますが、リストの代わりに “xrange オブジェクト” を返します。
このオブジェクトは不透明なシーケンス型で、対応するリストと同じ値を持ちますが、それらの値全てを同時に記憶しません。
 ragne() に対する xrange() の利点は微々たるものです (xrange() は要求に応じて値を生成するからです)
 ただし、メモリ量の厳しい計算機で巨大な範囲の値を使う時や、(ループがよく break で中断されるといったように) 範囲中の全ての値を使うとは限らない場合はその限りではありません。(
[http://docs.python.jp/2/library/functions.html#xrange:title]より)

ん?要はリストを作らずにそれに対応して実行する時に値を作っていくということでしょうか。
なんか多くなったら遅くなる気がするのは気のせいでしょうか。

実験環境

OS:X 10.9.2
CPU:2.8GHz IntelCore i7
メモリ:16GB 1600MHz DDR3

実験内容

xrange,rangeでの速度比較
特に何もしてません。長さ10000のリストで比較しました。

ソースコード

import numpy as np
import time

Time = 10
N = 10000

def list_sum_range(array):
	for i in range(Time):
		for j in range(len(array)):
			j

def list_array_sum_xrange(array):
	for i in range(Time):
		for j in xrange(len(array)):
			j

if __name__ == '__main__':
	array = [i for i in xrange(N)]
	list_array = [array,array]
	list_function = [list_sum_range,list_array_sum_xrange]

	for array,function in zip(list_array,list_function):
		start = time.time()
		function(array)
		print "%s" % ((time.time() - start) / Time)

結果

実験 速度
range 0.000310301780701
xrange 0.000260400772095

考察

xrangeの方が早いですね。必要に応じて値を取り出しているからなのでしょうか。
但し、メモリは間違いなくxrangeが少ないので、メモリを大量消費する場面ではxrangeを使っていきましょう。