1
df4VW 2015-04-24 22:14:55 +08:00
如果确保相互不影响,你不选后者的理由是?
|
2
ruandao 2015-04-24 22:19:35 +08:00 1
看有没有必要合并呗, 一般不是写的时候, 直接放在一起吗, 多打几个字,多写一个for 不麻烦吗?
如果是新的需求, 则把循环放在一个新的方法里面 |
3
MrEggNoodle 2015-04-24 22:22:48 +08:00
其实没所谓吧,各有各的代码习惯~除非公司做了限制。
|
4
cfan8 2015-04-24 22:23:32 +08:00
楼主需要的是函数式编程,就不会有这种困扰了= =
|
5
zhmin OP @df4VW 感觉第二种效率也没想象中的高吧,还是取决于do_somthing_1和do_somthing_2的复杂度。
最近接手同事的代码,第二种不好维护,往往一个for循环,里面的逻辑太多了,也不好拆分和维护 |
6
zts1993 2015-04-24 22:49:13 +08:00
for item in items:
process(item) def process(item): a() b() 这样呢? |
7
ryd994 2015-04-24 22:52:17 +08:00 via Android
效率没区别啊………
另外说不定编译器能优化掉呢? |
8
zipher 2015-04-24 22:53:33 +08:00
基本都被编译器优化了
哪种易读写哪种 |
9
Hyperion 2015-04-24 23:22:07 +08:00 1
会合并,就是因为不相关才放一起。
循环合并会优化,楼上两位能否告知下相关资料地址?真不知道python会合并… >>> def test(): ... items = ['cat', 'meow', 'dog', 'woof'] ... for item in items: ... print item ... for item in items: ... print item >>> dis.dis(test.func_code) 2 0 LOAD_CONST 1 ('cat') 3 LOAD_CONST 2 ('meow') 6 LOAD_CONST 3 ('dog') 9 LOAD_CONST 4 ('woof') 12 BUILD_LIST 4 15 STORE_FAST 0 (items) 3 18 SETUP_LOOP 19 (to 40) 21 LOAD_FAST 0 (items) 24 GET_ITER >> 25 FOR_ITER 11 (to 39) 28 STORE_FAST 1 (item) 4 31 LOAD_FAST 1 (item) 34 PRINT_ITEM 35 PRINT_NEWLINE 36 JUMP_ABSOLUTE 25 >> 39 POP_BLOCK 5 >> 40 SETUP_LOOP 19 (to 62) 43 LOAD_FAST 0 (items) 46 GET_ITER >> 47 FOR_ITER 11 (to 61) 50 STORE_FAST 1 (item) 6 53 LOAD_FAST 1 (item) 56 PRINT_ITEM 57 PRINT_NEWLINE 58 JUMP_ABSOLUTE 47 >> 61 POP_BLOCK >> 62 LOAD_CONST 0 (None) 65 RETURN_VALUE >>> |
12
secondwtq 2015-04-25 00:05:08 +08:00
一般习惯性放到一个循环里,大概最主要原因是讨厌“冗余”的 for。不过实际上我遇到大多数情况里面感觉两个循环任务还是有一些区别的。
如果是 Python 的话,我对其性能一直没有什么太大的好感,也并不希望能通过这种 trick 获得任何的提升。 |
14
mahone3297 2015-04-25 00:36:09 +08:00
确实是个问题。
为了可读性,我觉得分开比较好。。。 |
15
zhmin OP @Hyperion 我做了一个测试,
1 def func_1(x): 2 x += 1 3 4 def func_2(x): 5 x += 1 6 7 def test_1(): 8 for i in range(100000): 9 func_1(i) 10 func_2(i) 11 12 def test_2(): 13 data = range(100000) 14 for i in data: 15 func_1(i) 16 for i in data: 17 func_2(i) 18 19 if __name__ == "__main__": 20 import timeit 21 print(timeit.timeit("test_1()",number=1000, setup="from __main__ import test_1")) 22 print(timeit.timeit("test_2()",number=1000, setup="from __main__ import test_2")) 仅仅就是简单自增,输出结果为 31.7822570801 31.4160778522 看来即使编译器没优化, 但效率几乎没差别。 如果是更加复杂的处理,估计效率差距会更少 |
16
Hyperion 2015-04-25 00:57:35 +08:00
@zhmin 具体情况具体看(这句话好万能…),一般不会考虑这么细,而且写的时候考虑这个也很麻烦。
最后优化时候再考虑吧。 比如两个操作引用了什么共同对象,而且操作上没交集,我还是会放一起。或者是循环的次数很庞大,能并就并了。 实际工程经验较少,仅供参考。 |
17
sivacohan 2015-04-25 01:12:03 +08:00 via Android
两个写法表达的含义是不同的。
第一个是对列表整体的操作。可以理解为复杂的推导式。 第二个是对列表元素的操作,是对列表中每一个元素元素的基本操作。 至于效率,我的问题是,你的热点真的在这吗?没测试,别空谈优化。 |
18
chevalier 2015-04-25 01:15:43 +08:00
“代码是写给人看的,顺便也机器能跑”
|
19
Hyperion 2015-04-25 02:21:44 +08:00
@zhmin 理论上来说,JUMP_ABSOLUTE 次数越少当然是越好,不过跳转开销其实也并不多。分次执行,去掉gc 的影响,我这边测试下来。range(1000000) 测试1000次,合并也就好了那么一丢丢。
合并:445.608458035 分开:448.548615123 但其实也没有什么太大的意义。 话说#17 楼的理解反了吧?… |
20
Phoinikas 2015-04-25 10:41:15 +08:00
楼主你思路可能错了,你同事这么写的原因大概只是他觉得这样写可读性更高,而你的看法正好相反,这是没有标准的。
从效率上来说,循环本身是不耗时的(可以忽略),耗时的是循环里面的操作,两种写法中do_something_1和do_something_2执行的总数都是一样,所以测试出来两种写法的耗时并无大的区别。 |
21
notcome 2015-04-25 13:20:18 +08:00 via iPad
Python 的循环怎么可能合并,你得先看有没有副作用啊。
反正不追求速度,我觉得你爱怎么来怎么来。如果是我的话,我觉得合并的可读性较高,循环那一层在我看来是废话,而废话,能写一次就不要写两次。 但在其它语言中,这确实是可以合并的,比如 Haskell。 将一个列表里每一个元素加一,可以是: map (+1) list 全平方,可以是 map (^2) list 或者写清楚一点,f = (+1),g = (^2) 那么把一个表里所有数加一再平方,就是: map g (map f list) 但是不用担心,编译器会避免遍历两次表的,上述代码会被优化成: map (g . f) list 其中,点号代表函数……composition,中文啥来着? |
22
geeklian 2015-04-26 11:55:18 +08:00 via iPhone
怎么可读性高,怎么接近业务逻辑怎么来。
这么点性能都纠结,干嘛不换java.netc++ |