- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
出于好奇,我用 Python 编写了 3 个测试并使用 timeit 将它们超时:
import timeit
# simple range based on generator
def my_range(start, stop):
i = start
while (i < stop):
yield i
i += 1
# test regular range
def test_range():
x = range(1, 100000)
sum = 0
for i in x:
sum += i
# test xrange
def test_xrange():
x = xrange(1, 100000)
sum = 0
for i in x:
sum += i
# test my range
def test_my_range():
x = my_range(1, 100000)
sum = 0
for i in x:
sum += i
print timeit.timeit("test_range()", setup = "from __main__ import test_range", number = 100)
print timeit.timeit("test_xrange()", setup = "from __main__ import test_xrange", number = 100)
print timeit.timeit("test_my_range()", setup = "from __main__ import test_my_range", number = 100)
我有这些基准:
regular range based test - 0.616795163262
xrange based test - 0.537716731096
my_range (generator) based test - **1.27872886337**
我的范围甚至比创建列表的范围慢 X2。为什么?
xrange()
/range()
是直接用 C 实现的吗?
它们是否在没有条件检查的情况下实现?
谢谢!
最佳答案
我觉得简单的答案是 xrange()
是内置的并用 C 语言编写。
我在您的测试中添加了另一个案例(见下文):A pure-Python reference implementation xrange()
基于 CPython 源代码。
import timeit
from collections import Sequence, Iterator
from math import ceil
# simple range based on generator
def my_range(start, stop):
i = start
while (i < stop):
yield i
i += 1
# test regular range
def test_range():
x = range(1, 100000)
sum = 0
for i in x:
sum += i
# test xrange
def test_xrange():
x = xrange(1, 100000)
sum = 0
for i in x:
sum += i
# test my range
def test_my_range():
x = my_range(1, 100000)
sum = 0
for i in x:
sum += i
class pure_python_xrange(Sequence):
"""Pure-Python implementation of an ``xrange`` (aka ``range``
in Python 3) object. See `the CPython documentation
<http://docs.python.org/py3k/library/functions.html#range>`_
for details.
"""
def __init__(self, *args):
if len(args) == 1:
start, stop, step = 0, args[0], 1
elif len(args) == 2:
start, stop, step = args[0], args[1], 1
elif len(args) == 3:
start, stop, step = args
else:
raise TypeError('pure_python_xrange() requires 1-3 int arguments')
try:
start, stop, step = int(start), int(stop), int(step)
except ValueError:
raise TypeError('an integer is required')
if step == 0:
raise ValueError('pure_python_xrange() arg 3 must not be zero')
elif step < 0:
stop = min(stop, start)
else:
stop = max(stop, start)
self._start = start
self._stop = stop
self._step = step
self._len = (stop - start) // step + bool((stop - start) % step)
def __repr__(self):
if self._start == 0 and self._step == 1:
return 'pure_python_xrange(%d)' % self._stop
elif self._step == 1:
return 'pure_python_xrange(%d, %d)' % (self._start, self._stop)
return 'pure_python_xrange(%d, %d, %d)' % (self._start, self._stop, self._step)
def __eq__(self, other):
return isinstance(other, xrange) and \
self._start == other._start and \
self._stop == other._stop and \
self._step == other._step
def __len__(self):
return self._len
def index(self, value):
"""Return the 0-based position of integer `value` in
the sequence this xrange represents."""
diff = value - self._start
quotient, remainder = divmod(diff, self._step)
if remainder == 0 and 0 <= quotient < self._len:
return abs(quotient)
raise ValueError('%r is not in range' % value)
def count(self, value):
"""Return the number of ocurrences of integer `value`
in the sequence this xrange represents."""
# a value can occur exactly zero or one times
return int(value in self)
def __contains__(self, value):
"""Return ``True`` if the integer `value` occurs in
the sequence this xrange represents."""
try:
self.index(value)
return True
except ValueError:
return False
def __reversed__(self):
"""Return an xrange which represents a sequence whose
contents are the same as the sequence this xrange
represents, but in the opposite order."""
sign = self._step / abs(self._step)
last = self._start + ((self._len - 1) * self._step)
return pure_python_xrange(last, self._start - sign, -1 * self._step)
def __getitem__(self, index):
"""Return the element at position ``index`` in the sequence
this xrange represents, or raise :class:`IndexError` if the
position is out of range."""
if isinstance(index, slice):
return self.__getitem_slice(index)
if index < 0:
# negative indexes access from the end
index = self._len + index
if index < 0 or index >= self._len:
raise IndexError('xrange object index out of range')
return self._start + index * self._step
def __getitem_slice(self, slce):
"""Return an xrange which represents the requested slce
of the sequence represented by this xrange.
"""
start, stop, step = slce.start, slce.stop, slce.step
if step == 0:
raise ValueError('slice step cannot be 0')
start = start or self._start
stop = stop or self._stop
if start < 0:
start = max(0, start + self._len)
if stop < 0:
stop = max(start, stop + self._len)
if step is None or step > 0:
return pure_python_xrange(start, stop, step or 1)
else:
rv = reversed(self)
rv._step = step
return rv
def __iter__(self):
"""Return an iterator which enumerates the elements of the
sequence this xrange represents."""
return xrangeiterator(self)
class xrangeiterator(Iterator):
"""An iterator for an :class:`xrange`.
"""
def __init__(self, xrangeobj):
self._xrange = xrangeobj
# Intialize the "last outputted value" to the value
# just before the first value; this simplifies next()
self._last = self._xrange._start - self._xrange._step
self._count = 0
def __iter__(self):
"""An iterator is already an iterator, so return ``self``.
"""
return self
def next(self):
"""Return the next element in the sequence represented
by the xrange we are iterating, or raise StopIteration
if we have passed the end of the sequence."""
self._last += self._xrange._step
self._count += 1
if self._count > self._xrange._len:
raise StopIteration()
return self._last
# test xrange
def test_pure_python_xrange():
x = pure_python_xrange(1, 100000)
sum = 0
for i in x:
sum += i
print timeit.timeit("test_range()", setup = "from __main__ import test_range", number = 100)
print timeit.timeit("test_xrange()", setup = "from __main__ import test_xrange", number = 100)
print timeit.timeit("test_my_range()", setup = "from __main__ import test_my_range", number = 100)
print timeit.timeit("test_pure_python_xrange()", setup = "from __main__ import test_pure_python_xrange", number = 100)
结果?
$ python so.py
0.426695823669
0.371111869812
0.964643001556
6.06390094757
这只是解释型 Python 代码和 C 之间的区别。此外,正如@byels 上面提到的,xrange()
仅限于短整数,这可能会产生积极影响。
关于Python:为什么我的基于生成器的范围比 xrange 慢 X2?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31928459/
在下面的代码片段中, if evaluation_data: n_data = len(evaluation_data) n = len(training_data) eval
我正在从传感器捕获数据,并将其输出到 .dat 文件中。我想使用 gnuplot 将此信息导出到绘图中,并使其完全自主地仅显示最近 7 天收集的数据(没有对日期进行硬编码,应使用 time() 函数根
我尝试绘制一个包含 YEAR-MONTH-DAY HOUR 格式的时间戳的文件和一个由制表符分隔的正整数。 GNUPlot 似乎无法提取给定文件的开始结束时间告诉我 Warning: empty x
这个问题已经有答案了: Why doesn't modifying the iteration variable affect subsequent iterations? (10 个回答) 已关闭
片段 xi = xrange(10) zip(xi,xi) 和 xi = iter(range(10)) zip(xi,xi) 行为不同。我希望得到 [(0, 1), (2, 3), (4
我想创建一个 Highcharts xrange 图表,其中仅显示适合框/范围的数据标签。这可能吗? 目前,标签不会重叠,但在不适合时会显示在框外。 我尝试使用 xrange.dataLabels 选
我想创建一个 xrange highcharts。据此demo ,他们使用 UTC 格式创建日期,但我从 MySQL 的 json 输出是这样的 [{"y":1,"x":"2018-01-19 08:
我不确定标题的措辞是否正确,但我想做的是找到 xrange() 传递的值的总和。 理想情况下,它看起来像这样:(注意,这不是工作代码) mofthree = xrange(2, 1000, 3) mo
在 Python 中,迭代时使用 xrange() 而不是 range 更节省内存。 我遇到的问题是我想遍历一个大列表——因此我需要使用 xrange() 然后我想检查任意元素。 使用 range()
我在尝试在网络应用程序中显示 Xrange 图表时遇到问题。 一切正常,直到我尝试缩放图表并且数据输入的极端之一落在视口(viewport)之外,从那时起图形表示就不再显示。 chart: {
我想像下面这样显示我的图表。我为此使用了“xrange”类型的 Highcharts 。我正在尝试为每个数据点显示一个事件,其中将有一个开始数据和一个结束日期。 到目前为止,我能够使用 xrange
我有一个 xrange highchart,其中有一个系列,其中一些数据点具有重叠值。当鼠标指针悬停在特定数据点上时,我需要获取重叠数据点的值一次。我尝试使用系列 mouseover 事件,但从中我只
我正在尝试使用 ctypes 从内部 python 结构中提取数据。也就是说,我正在尝试读取 xrange 中的 4 个字段: typedef struct { PyObject_HEAD
为什么 zip(*[xrange(5)]*2) 给出 [(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)] 但是 zip(*[iter(xrange(5))]*2) 给出
我是python和django的新手。我的django在我的机器上正常运行,直到安装django-haystack。我直接从github下载django-haystack.zip,并在haystack
我正在使用此 jsfiddle 创建一个 xrange Highcharts 作为引用。 如何将值传递给列表中的“x”、“x2”、“y”值? 对于普通的柱形图/条形图,我会执行以下操作,效果很好。 v
操作 myInput 字符串以获得 myOutput 字符串的更快方法是什么? myInput = "1,3-5,7" myOutput = "1,3,4,5,7" 最佳答案 re.sub(
这个问题在这里已经有了答案: How do I concatenate two lists in Python? (31 个答案) 关闭 6 年前。 我有这个正在工作的数组: urls = [
我编写了以下代码来在文本文件中定义 4 行的 block ,如果 block 的第 2 行仅由一种字符组成,则输出该 block 。假设(并且之前已验证)第 2 行始终由 36 个字符的字符串组成。
出于好奇,我用 Python 编写了 3 个测试并使用 timeit 将它们超时: import timeit # simple range based on generator def my_ran
我是一名优秀的程序员,十分优秀!