三种写法,耗时从高到低,如下面代码所示,输出结果一样。各位大佬帮忙看下原因?
a = ''
for i in range(100000):
a = a+str(i)+'->'
b = ''.join([str(i)+'->' for i in range(100000)])
c = '->'.join(map(str, range(100000)))+'->'
输出结果:0->1->2->3->4->5->6->7->8->9...->99998->99999->
1
mxT52CRuqR6o5 188 天前
for 相比 join 会生成大量的 string 中间状态影响性能吧
|
![]() |
2
sujin190 188 天前 ![]() 你这分明是内存复制的问题,和 Python 毛关系没有吧,第一个慢的循环内存申请和复制量随着循环次数增加会指数增长,啥语言都会慢很多
|
![]() |
3
Mohanson 188 天前
思考下字符串加法.
|
![]() |
4
metaquant 188 天前
这个和 python 循环的效率无关,而是因为 python 中字符串是 immutable 的,每次拼接字符串都会产生复制一个新的字符串变量,开销较大,所以涉及大量字符串拼接时,正确的做法是使用第二和第三种方法中的 join , 所以你可以发现第二和第三种方法的差距很小。
|
![]() |
5
sujin190 188 天前
如果你在 c 或者 java 直接仅仅写这么一段也很快,那大概率是被编译器展开优化掉了,关掉编译优化再看看
|
6
wxf666 188 天前 ![]() 你换成 a += str(i)+'->' 就差不多一样了
|
7
qianc1990 188 天前
第一个时间主要花在每次循环的字符串拼接上了
|
![]() |
8
churchill 188 天前
😄
``` function test() { a = '' for (let i=0; i<100000; i++) a = a+i+'->' return a } test() console.time("python sucks") test() console.timeEnd("python sucks") VM809:9 python sucks: 19.73193359375 ms ``` |
9
lingly02 188 天前
function test2() {[...Array(10000).keys()].map((i)=>i+'->').join('')}
console.time("python sucks") test2() console.timeEnd("python sucks") VM1332:3 python sucks: 1.7998046875 ms |
![]() |
10
nekochyan 188 天前
第一个你是不是看错时间了,不是 7.8s 而是 0.78s ,我实测耗时 0.8s 左右
js 测试我跟楼上一样只需要 13ms 左右就完成循环了 |
11
wxf666 188 天前
这个例子中,Google 花这么多钱搞的 V8 ,也没甩开 Python 多少啊?
这 8 楼 9 楼( 9 楼还少了个数量级)和楼主的没 JIT 的 Python 一比(第一个例子改成 += 就好),也没快多少啊 |
![]() |
12
ipwx 188 天前
无论什么语言,大量小字符串直接拼接都会有严重的性能问题。
|
13
aloxaf 188 天前
见 wtrfpython: https://github.com/satwikkansal/wtfpython#section-miscellaneous
顺便本机测了一下,方法一 700 ms ,换 bytearray 只要 20ms a = bytearray() for i in range(100000): a.extend((str(i) + '->').encode()) a = a.decode() |
14
wyc9296 OP |
16
xgdgsc 188 天前 via Android
就是很差的,julia 用 PythonCall.jl 用 julia 的 for 循环调用 python 函数随便比 python 快几个数量级
|
17
houzhiqiang 188 天前
```python
import time def test(n: int = 100000): # return '->'.join([f'{x}' for x in range(n)]) + '->' return '->'.join(map(str, range(n))) + '->' start = time.time() test() print(f"used: {(time.time() - start) * 1000}ms") ``` cpython3.10.3 time python test.py used: 19.52505111694336ms python test.py 0.05s user 0.03s system 87% cpu 0.096 total pypy3.9-7.3.9 time pypy test.py used: 7.740020751953125ms pypy test.py 0.06s user 0.04s system 89% cpu 0.118 total #9 @lingly02 的代码 node v16.14.2 time node test.js python sucks: 3.757ms node test.js 0.05s user 0.02s system 95% cpu 0.069 total |
19
wxf666 188 天前
@houzhiqiang 看起来日用差距不大,真要求性能,还是上 C/C++ 之类的吧,wasm 都没用(比如 squoosh 转码 avif ,比本地 avifenc 慢太多)
|
20
HankLu 188 天前
判断一个字符串是否在一个巨大的文本里面怎么样最快?
|
21
houzhiqiang 188 天前
#8 @churchill 的代码
node v16.14.2 time node test.js python sucks: 26.584ms node test.js 0.10s user 0.02s system 98% cpu 0.124 total #9 @lingly02 的代码 把他的 Array(10000)换成 Array(100000) node v16.14.2 time node test.js python sucks: 24.985ms node test.js 0.06s user 0.02s system 97% cpu 0.084 total @houzhiqiang |
22
houzhiqiang 188 天前
|
23
wxf666 188 天前
|
24
wxf666 188 天前
|
![]() |
25
churchill 188 天前
这。。。我就是打个趣,代码是按楼主的第一种写法原封不动搬来的
性能这个事情 python 也还是要挣扎一下吗,大可不必 黑魔法的话 js 也有呀 warm 一下立杆见影 test() setTimeout(() => { console.time("python sucks") test() console.timeEnd("python sucks") }) |
26
lingly02 187 天前 via iPhone
@houzhiqiang 上班摸鱼,看错数量了,😅
|
![]() |
28
Elaina 187 天前
是字符串拼接影响效率,你把字符串拼接改成空操作,就没这么夸张了
|
30
zhuweiyou 187 天前
字符串拼接的问题
|
31
xgdgsc 187 天前
@wxf666 for 循环里先读取 memmap 的 array 里一个数,然后调用函数,这种情况反正用 julia 比 python 至少快一个数量级,我用几只不过想不起来具体快多少了,并不是说一定大于等于 3 才用几.
|
33
w3cll 187 天前
蹲一个 PHP 的
|
![]() |
34
pytth 187 天前
```
<?php $starttime = explode(' ',microtime()); for($i=0; $i<100000; $i++){ echo $i.'<br/>'; } $endtime = explode(' ',microtime()); $thistime = $endtime[0]+$endtime[1]-($starttime[0]+$starttime[1]); $thistime = round($thistime,3); echo '用时'.$thistime; ?> ``` <img src="https://sc01.alicdn.com/kf/Ha0b06a519774459597cb42b339bd7ecbx.png" /> @w3cll |
36
wxf666 187 天前
|
38
jinliming2 187 天前 via iPhone
@pytth #34 你这个 echo 是流输出啊,不是字符串拼接,有点作弊了哦……
|
![]() |
39
Anivial 187 天前
一个提问贴能多这么多阴阳怪气的人也是没谁了,以后看见歪楼的就走,无语死
|