- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
令人惊讶的是,我发现 startswith
比 in
慢:
In [10]: s="ABCD"*10
In [11]: %timeit s.startswith("XYZ")
1000000 loops, best of 3: 307 ns per loop
In [12]: %timeit "XYZ" in s
10000000 loops, best of 3: 81.7 ns per loop
众所周知,in
操作需要搜索整个字符串,而startswith
只需要检查前几个字符,所以startswith
应该更有效率。
当s
足够大时,startswith
会更快:
In [13]: s="ABCD"*200
In [14]: %timeit s.startswith("XYZ")
1000000 loops, best of 3: 306 ns per loop
In [15]: %timeit "XYZ" in s
1000000 loops, best of 3: 666 ns per loop
所以调用 startswith
似乎有一些开销,这使得当字符串很小时它会变慢。
然后我试图弄清楚 startswith
调用的开销是多少。
首先,我使用了一个 f
变量来降低点运算的成本——正如本文 answer 中所提到的。 - 这里我们可以看到 startswith
仍然比较慢:
In [16]: f=s.startswith
In [17]: %timeit f("XYZ")
1000000 loops, best of 3: 270 ns per loop
此外,我测试了空函数调用的成本:
In [18]: def func(a): pass
In [19]: %timeit func("XYZ")
10000000 loops, best of 3: 106 ns per loop
不考虑点操作和函数调用的成本,startswith
的时间大约是(270-106)=164ns,但是in
操作只需要81.7 ns。 startswith
似乎还有一些开销,那是什么?
按照 poke 和 lvc 的建议在 startswith
和 __contains__
之间添加测试结果:
In [28]: %timeit s.startswith("XYZ")
1000000 loops, best of 3: 314 ns per loop
In [29]: %timeit s.__contains__("XYZ")
1000000 loops, best of 3: 192 ns per loop
最佳答案
正如评论中已经提到的,如果你使用 s.__contains__("XYZ")
你得到的结果更类似于 s.startswith("XYZ")
因为它需要走相同的路线:在字符串对象上查找成员,然后调用函数。这通常有点贵(当然还不够你应该担心)。另一方面,当您在 s 中执行 "XYZ"时,解析器会解释该运算符并可以快捷地访问
__contains__
的成员访问(或者更确切地说是后面的实现它,因为 __contains__
本身只是访问实现的一种方式)。
您可以通过查看字节码来了解这一点:
>>> dis.dis('"XYZ" in s')
1 0 LOAD_CONST 0 ('XYZ')
3 LOAD_NAME 0 (s)
6 COMPARE_OP 6 (in)
9 RETURN_VALUE
>>> dis.dis('s.__contains__("XYZ")')
1 0 LOAD_NAME 0 (s)
3 LOAD_ATTR 1 (__contains__)
6 LOAD_CONST 0 ('XYZ')
9 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
12 RETURN_VALUE
因此,比较 s.__contains__("XYZ")
与 s.startswith("XYZ")
会产生更相似的结果,但是对于您的示例字符串 s
,startswith
还是会比较慢。
为此,您可以检查两者的实现。有趣的是 contains implementation是它是静态类型的,只是假设参数本身是一个 unicode 对象。所以这是非常有效的。
startswith
implementation然而,它是一种“动态” Python 方法,它需要实现来实际解析参数。 startswith
还支持一个元组作为参数,这使得方法的整个启动有点慢:(由我缩短,并附上我的评论):
static PyObject * unicode_startswith(PyObject *self, PyObject *args)
{
// argument parsing
PyObject *subobj;
PyObject *substring;
Py_ssize_t start = 0;
Py_ssize_t end = PY_SSIZE_T_MAX;
int result;
if (!stringlib_parse_args_finds("startswith", args, &subobj, &start, &end))
return NULL;
// tuple handling
if (PyTuple_Check(subobj)) {}
// unicode conversion
substring = PyUnicode_FromObject(subobj);
if (substring == NULL) {}
// actual implementation
result = tailmatch(self, substring, start, end, -1);
Py_DECREF(substring);
if (result == -1)
return NULL;
return PyBool_FromLong(result);
}
这可能是 startswith
对于 contains
的字符串较慢的一个重要原因,因为它很简单。
关于python - 为什么字符串的startswith比in慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31917372/
我使用的是 Java 版本 1.8.0_31。 我正在尝试使用 FileVisitor 接口(interface)递归访问目录树。该程序应打印 C:/books 中文件名以“Ver”开头的所有文件的名
我有一个 Java 方法,它接受类型的参数 interface Function2 { TR apply(TP1 p1, TP2 p2) } 以及像这样的 Java 方法 boolean cont
我有一个给我带来麻烦的功能。下面的代码返回错误消息“无法读取未定义的属性‘值’”。该函数应该只搜索帐户列表中的值并返回以提交的字符串开头的值。在示例中,提交“000555”应返回 0。 var acc
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 4 年前。 Improve th
所以我有一个问题。今天我开始优化我的代码并达到了这一点,例如: return !this.message.startsWith("/"); 请遵循我从 here 获取优化技巧的地方。 (链接到规则)
我仍在使用 Java 开发一个项目,想问问是否有人可以帮助我? 我问我是否有可能用“startsWith”来检查一个包含多个字母的字符串? 喜欢: if (string Alpha.startsWi
类项目要求我们读取单个文本文件中包含的 10,514 首歌曲的标题、艺术家和歌词。该项目的当前部分让我们编写一个有序的展开链接列表并在标题字段上运行搜索。还编写了比较器来按标题对列表进行排序。我们必须
我加入了两个列表,一个包含总线路径,另一个包含作为总线子路径的磁盘路径。所以基本上我想加入 diskpath.startswith(buspath)。问题是 Join On 只允许在 equals 的
我有这个代码: for (var i = 0; i TypeError: r[e].startsWith is not a function > at js-cf2cc68….min.js.g
我正在阅读 Microsoft 的 Best Practices for Using Strings in the .NET Framework . 它给出了以下示例作为对 StringCompari
我正在寻找一个集合来存储键值对,其中值应该根据键 startswith 条件返回。 例如对于给定的集合:(a,123) (ab,234) (abcd,5434) 如果我执行 map.get(a) 它应
有没有办法检查一个字符串是否以不同的字母开头,而不是只检查一次。 下面是我当前的代码: myString.startsWith('M') || myString.startsWith('L
函数:startswith() 作用:判断字符串是否以指定字符或子字符串开头 1、函数说明 语法:string.startswith(str, beg=0,end=len(string))
在网站上没有找到这个,但我确实找到了 open bug on Github在撰写本文时,唯一的解决方案是使用 GatsbyImage。学习将 Gatsby 项目从 2 转换为 3 我已经安装了 gat
我是 PowerShell 的新手,如果字符串不是以特定字符开头,我正在尝试运行一些代码,但是我无法让它处理多个字符。 这是工作正常的代码。 if (-Not $recdata.StartsWith
我需要查看文本的第一行是否以 By 开头,如果是,则剪切整行并将其存储在变量中,并删除所有空白行,直到下一段开始。查找 By 的方法需要不区分大小写,并且前面也可能有一些空格。如果第一行不是以 By
当我像这样使用 odata 时:$filter=startswith(tolower(firstName),tolower('A'))它不起作用。 我想知道tolower和toupper是否可以和st
这个问题在这里已经有了答案: Conditional statement inside a match case (2 个答案) 关闭 4 个月前。 有没有办法像下面这样使用匹配大小写来选择字符串结
我有一个这样的查找: Lookup plsBase = (Lookup)(Query($@"Select ...").ToLookup(s => s.ip, o => o)); 当我通过按键访
当我像这样使用 odata 时:$filter=startswith(tolower(firstName),tolower('A'))它不起作用。 我想知道tolower和toupper是否可以和st
我是一名优秀的程序员,十分优秀!