在 Python 中切片两次

问题描述 投票:0回答:1

通常我有一个偏移量和数据长度,我想从 str 或 bytes 中提取数据。

我最常看到的方式是:

mystr[ offset: offset+length ]

改为执行以下操作(这似乎更容易理解)效率会降低多少?

mystr[ offset: ][ :length ]

如果数据实际上被复制了两次,并且为每个副本分配了内存,那么效率会非常低。但如果它是用指针和引用计数魔法完成的,也许效率不会低很多?它甚至可以被优化。

这也引出了更长的切片操作组合的效率问题,尽管到目前为止我还没有发现需要更多。

python performance slice
1个回答
0
投票

TLDR

绳子越长,越吸

mystr[ offset: ][ :length ]
mystr[ offset: offset+length ]

相比

背景:

你可以

timeit
如果你喜欢并且结果是戏剧性的(至少对于香草蟒蛇和莎士比亚全集),

mystr[ offset: offset+length ]
mystr[ offset: ][ :length ]
快几个数量级。

import timeit

setup = """
offset = 1000
length = 1000
with open("shakespeare.txt", "r", encoding="utf-8") as file_in:
    mystr = file_in.read()

def test1(mystr):
    return mystr[ offset: offset+length ]

def test2(mystr):
    return mystr[ offset: ][ :length ]
"""

print(f"Test1: {timeit.timeit('test1(mystr)', setup=setup, number=1000)}")
print(f"Test2: {timeit.timeit('test2(mystr)', setup=setup, number=1000)}")

在装有莎士比亚全集的笔记本电脑上,我得到如下结果:

Test1: 0.00045
Test2: 2.98909

请注意,所讨论的文本相当长,文本较短,结果并没有那么糟糕。

import timeit

setup = """
offset = 1000
length = 1000
with open("shakespeare.txt", "r", encoding="utf-8") as file_in:
    mystr = file_in.read()[:3000]

def test1(mystr):
    return mystr[ offset: offset+length ]

def test2(mystr):
    return mystr[ offset: ][ :length ]
"""

print(f"Test1: {timeit.timeit('test1(mystr)', setup=setup, number=1000)}")
print(f"Test2: {timeit.timeit('test2(mystr)', setup=setup, number=1000)}")

用那个较短的字符串我得到:

Test1: 0.00045
Test2: 0.00081

请注意,

test1()
的时间并没有随着文本的长度而变化,而文本越长,
test2()
变得越慢。

© www.soinside.com 2019 - 2024. All rights reserved.