列表、numpy、pandas Series字符串索引[0]与[0:1]性能差异疑问
性能差异原因说明
这三类场景的性能差异是单值索引与切片的原生底层逻辑差异 + 不同数据结构对[]操作的自定义实现差异共同导致的,各场景的具体原因如下:
原生Python字符串列表场景
Python原生层面,x[0]和x[0:1]就是完全不同的两类操作,即便返回结果看起来一致:
x[0]是单值索引:底层C实现仅需1次边界校验,直接按偏移量读取对应位置的字符,逻辑极简x[0:1]是切片操作:需要先创建切片对象、校验起止两个索引的合法性、处理负数索引、计算切片长度,最后才会读取对应区间内容,额外开销远高于单值索引
因此原生场景下x[0]的性能优势非常明显,可达60%-90%。
Numpy字符串数组场景
Numpy的字符串数组采用定长存储(本次测试中的'ABC'对应dtype为<U3,固定占用3个Unicode字符的存储空间),无论单值索引还是切片操作,首先都需要将Numpy内部存储的定长字符串转换为Python原生字符串对象,这部分转换开销占总耗时的90%以上,直接稀释了单值索引本身的性能优势,最终两者性能差距被压缩到10%左右。
Pandas Series.str访问器场景
该场景的性能反转完全由Pandas的自定义实现逻辑导致,在测试使用的1.3.4版本中:
series.str[n]单值索引的实现:逐元素检查字符串长度,若长度小于n则返回NaN,再提取对应位置字符,整个过程为逐元素Python级循环,未做定向的向量化优化,长序列下开销极高series.str[start:end]切片的实现:底层采用Cython做了向量化优化,批量处理所有元素的切片操作,越界场景直接返回空字符串,不需要额外的NaN判断开销,长序列下性能优势突出
小数据量时,两者耗时主要由.str访问器的初始化开销决定,差异极小;数据量越大,切片的向量化优势越明显,因此会出现[0:1]比[0]快50%以上的情况。
内容的提问来源于stack exchange,提问作者Vinson Ciawandy
相关产品推荐
相关产品推荐

