标签: python-internals

Python:多项任务与个人分配速度

我一直在寻求从我的代码中获得更多的性能; 最近,在浏览这个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

9
推荐指数
1
解决办法
1222
查看次数

在Python中,f.readlines()和list(f)之间有什么区别

Python2教程Python3教程中,在7.2.1节的中点都有一行说:

如果要读取列表中文件的所有行,也可以使用list(f)f.readlines().

所以我的问题是:将文件对象转换为列表的这两种方法有什么区别?我在性能方面和Python对象实现中都很好奇(也许是Python2和Python3之间的区别).

python file-io file list python-internals

9
推荐指数
1
解决办法
1060
查看次数

为什么旧样式类的实例是`object`的实例?

在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),但显然我错过了一些东西.

python class python-2.x isinstance python-internals

9
推荐指数
0
解决办法
227
查看次数

为什么python中的函数/方法调用很昂贵?

这篇文章中,Guido van Rossum说功能调用可能很昂贵,但我不明白为什么也不贵.

多少延迟会为您的代码添加一个简单的函数调用,为什么?

python profiling function-calls python-internals

8
推荐指数
3
解决办法
5591
查看次数

为什么Python 2中的生成器表达式和字典/集合理解使用嵌套函数而不像列表推导?

列表推导将其代码直接放在使用它们的函数中,如下所示:

>>> 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 bytecode python-internals

8
推荐指数
1
解决办法
179
查看次数

比较int和float时Python什么时候进行类型转换?

为什么Python中返回True时,我比较intfloat具有相同价值的物品?

例如:

>>> 5*2 == 5.0*2.0
True
Run Code Online (Sandbox Code Playgroud)

python floating-point int python-3.x python-internals

8
推荐指数
1
解决办法
3005
查看次数

为什么f字符串比str()解析值快?

我正在玩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 python-3.x python-internals python-3.6 f-string

8
推荐指数
1
解决办法
383
查看次数

Python 基本类型的内存使用(尤其是 int 和 float)

这是来自 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 memory-management python-internals

8
推荐指数
1
解决办法
3047
查看次数

Python中多键排序的效率

我有一个字符串列表,我想按 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 sorting python-internals

8
推荐指数
1
解决办法
1141
查看次数

list[str] 是可迭代的吗?

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 python-internals python-typing

8
推荐指数
2
解决办法
993
查看次数