我一直在寻求从我的代码中获得更多的性能; 最近,在浏览这个Python维基页面时,我发现了这个主张:
多次分配比单独分配慢.例如,"x,y = a,b"比"x = a; y = b"慢.
好奇,我测试了它(在Python 2.7上):
$ python -m timeit "x, y = 1.2, -1.4"
10000000 loops, best of 3: 0.0365 usec per loop
$ python -m timeit "x = 1.2" "y = -1.4"
10000000 loops, best of 3: 0.0542 usec per loop
Run Code Online (Sandbox Code Playgroud)
我以不同的顺序重复了几次,等等,但多重赋值片段的表现始终比个人作业至少好30%.显然,我的代码涉及变量赋值的部分不会成为任何重大瓶颈的根源,但我的好奇心仍然被激发了.当文档另有说明时,为什么多项任务明显快于个人任务?
编辑:
我测试了两个以上变量的赋值,得到了以下结果:

趋势似乎或多或少一致; 任何人都可以复制它吗?
(CPU:Intel Core i7 @ 2.20GHz)
python performance variable-assignment timeit python-internals
从Python2教程和Python3教程中,在7.2.1节的中点都有一行说:
如果要读取列表中文件的所有行,也可以使用
list(f)或f.readlines().
所以我的问题是:将文件对象转换为列表的这两种方法有什么区别?我在性能方面和Python对象实现中都很好奇(也许是Python2和Python3之间的区别).
在Python 2中,为什么旧样式类的实例仍然是实例,object即使它们没有显式继承object?
class OldClass:
pass
>>> isinstance(OldClass(), object)
True
Run Code Online (Sandbox Code Playgroud)
在测试之前,我会得出结论,isinstance(x, object) == True这意味着它x是一个子类object的实例,因此是新样式类的一个实例,但似乎Python 2中的所有对象都是实例object(是的,我知道声音有多明显) ).
进一步挖掘,我发现了一些看似奇怪的行为:
>>> issubclass(OldClass, object)
False
Run Code Online (Sandbox Code Playgroud)
我的印象isinstance(x, SomeClass)实际上相当于issubclass(x.__class__, SomeClass),但显然我错过了一些东西.
在这篇文章中,Guido van Rossum说功能调用可能很昂贵,但我不明白为什么也不贵.
多少延迟会为您的代码添加一个简单的函数调用,为什么?
列表推导将其代码直接放在使用它们的函数中,如下所示:
>>> dis.dis((lambda: [a for b in c]))
1 0 BUILD_LIST 0
3 LOAD_GLOBAL 0 (c)
6 GET_ITER
>> 7 FOR_ITER 12 (to 22)
10 STORE_FAST 0 (b)
13 LOAD_GLOBAL 1 (a)
16 LIST_APPEND 2
19 JUMP_ABSOLUTE 7
>> 22 RETURN_VALUE
Run Code Online (Sandbox Code Playgroud)
而生成器表达式和字典/集合理解主要放在一个单独的嵌套函数中,如下所示:
>>> dis.dis((lambda: {a for b in c}))
1 0 LOAD_CONST 1 (<code object <setcomp> at 0x7ff41a3d59b0, file "<stdin>", line 1>)
3 MAKE_FUNCTION 0
6 LOAD_GLOBAL 0 (c)
9 GET_ITER
10 CALL_FUNCTION 1
13 RETURN_VALUE
>>> dis.dis((lambda: {a for …Run Code Online (Sandbox Code Playgroud) 为什么Python中返回True时,我比较int和float具有相同价值的物品?
例如:
>>> 5*2 == 5.0*2.0
True
Run Code Online (Sandbox Code Playgroud) 我正在玩f字符串(请参阅PEP 498),因此我决定检查f字符串解析(例如f“ {1}”)的速度与通常的str解析(例如str(1) ))。但是令我惊讶的是,当我使用timeit函数检查两种方法的速度时,我发现
>>> from timeit import timeit
>>> timeit("f'{1}'")
0.1678762999999961
Run Code Online (Sandbox Code Playgroud)
而
>>> timeit("str(1)")
0.3216999999999999
Run Code Online (Sandbox Code Playgroud)
甚至是repr func,在大多数情况下,它们都比str转换快
>>> timeit("repr(1)")
0.2528296999999995
Run Code Online (Sandbox Code Playgroud)
我不知道为什么呢?我以为f弦在内部调用了str,但是现在,我有点困惑了,有什么想法吗?提前致谢!
PD:就像有人想知道的那样:
assert f"{1}" == str(1) == repr(1)
Run Code Online (Sandbox Code Playgroud) 这是来自 Python 3.8.0 解释器的示例(但是,它在 3.7.5 中类似)
>>> import sys
>>> sys.getsizeof(int)
416
>>> sys.getsizeof(float)
416
>>> sys.getsizeof(list)
416
>>> sys.getsizeof(tuple)
416
>>> sys.getsizeof(dict)
416
>>> sys.getsizeof(bool)
416
Run Code Online (Sandbox Code Playgroud)
getsizeof()返回 Python 对象消耗的字节数以及垃圾收集器的开销(参见此处)。基本python类消耗相同数量的内存的原因是什么?
如果我们看一下这些类的实例
>>> import sys
>>> sys.getsizeof(int())
24
>>> sys.getsizeof(float())
24
Run Code Online (Sandbox Code Playgroud)
默认参数是,0并且这两个实例对此参数具有相同的内存使用量。但是,如果我尝试添加一个参数
>>> sys.getsizeof(int(1))
28
>>> sys.getsizeof(float(1))
24
Run Code Online (Sandbox Code Playgroud)
这就是奇怪的地方。为什么 int 类型的实例内存使用量增加,而 float 类型的实例内存使用量没有增加?
我有一个字符串列表,我想按 Python 3.6 中的两个自定义键函数对其进行排序。将多排序方法(按较小键排序,然后按主键排序)与多键方法(将键作为元组(major_key, lesser_key))进行比较,我可以看到后者比前者慢 2 倍以上,这是惊讶,因为我认为它们是等价的。我想了解为什么会这样。
import random
from time import time
largest = 1000000
length = 10000000
start = time()
lst = [str(x) for x in random.choices(range(largest), k=length)]
t0 = time() - start
start = time()
tmp = sorted(lst, key=lambda x: x[::2])
l1 = sorted(tmp, key=lambda x: ''.join(sorted(x)))
t1 = time() - start
start = time()
l2 = sorted(lst, key=lambda x: (''.join(sorted(x)), x[::2]))
t2 = time() - start
print(f'prepare={t0} multisort={t1} multikey={t2} slowdown={t2/t1}')
assert l1 == l2
Run Code Online (Sandbox Code Playgroud) Python 3.10 不这么认为:
Python 3.10.6 | packaged by conda-forge | (main, Aug 22 2022, 20:38:29) [Clang 13.0.1 ] \
on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from typing import Iterable
>>> isinstance(list[str], Iterable)
False
>>> list(list[str])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'types.GenericAlias' object is not iterable
Run Code Online (Sandbox Code Playgroud)
Python 3.11 认为它是:
Python 3.11.0 | packaged by conda-forge | (main, Jan 15 2023, 05:44:48) [Clang 14.0.6 ] \
on darwin
Type …Run Code Online (Sandbox Code Playgroud) python ×10
python-internals ×10
python-3.x ×2
bytecode ×1
class ×1
f-string ×1
file ×1
file-io ×1
int ×1
isinstance ×1
list ×1
performance ×1
profiling ×1
python-2.x ×1
python-3.6 ×1
sorting ×1
timeit ×1