
import pika import sys import time connection = pika.BlockingConnection(pika.ConnectionParameters( host='localhost')) channel = connection.channel() channel.queue_declare(queue='task_queue', durable=True) message = '1' start = time.time() for i in range(1000): channel.basic_publish(exchange='', routing_key='task_queue', body=message, properties=pika.BasicProperties( delivery_mode = 2, # make message persistent )) end = time.time() print end - start connection.close() import java.util.Date; import java.util.concurrent.TimeoutException; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; import com.rabbitmq.client.ConnectionFactory; import com.rabbitmq.client.MessageProperties; public class Producer { private static final String TASK_QUEUE_NAME = "task_queue"; public static void main(String[] argv) throws java.io.IOException, TimeoutException { ConnectionFactory factory = new ConnectionFactory(); factory.setHost("localhost"); Connection connection = factory.newConnection(); Channel channel = connection.createChannel(); channel.queueDeclare(TASK_QUEUE_NAME, true, false, false, null); String message = "1"; long start = new Date().getTime(); for(int i = 0; i < 1000; ++i) { channel.basicPublish( "", TASK_QUEUE_NAME, MessageProperties.PERSISTENT_TEXT_PLAIN, message.getBytes()); } long end = new Date().getTime(); System.out.println(end - start); channel.close(); connection.close(); } } 1 c742435 2015-11-02 10:48:44 +08:00 你的 python 解释器是什么 有很多高性能的解释器可以试试 |
2 fengxiang 2015-11-02 10:53:41 +08:00 via Android 那就卸了蛇用 java 喽 |
3 eightqueen OP @c742435 我用的 mint 系统,就是预装的 python 喽,应该是 cpython 吧 |
4 loading 2015-11-02 11:07:07 +08:00 via Android let's go. |
5 tabris17 2015-11-02 11:14:21 +08:00 python 当然慢咯,一直如此啊 即便是 pypy 和 JAVA 比也是慢的 |
6 leavic 2015-11-02 12:08:00 +08:00 python 如果性能和 jva 一样, java 早死了 |
7 sujin190 2015-11-02 12:11:46 +08:00 哈哈,当时用 python 写完再用 java 实现对比的时候一样感觉,但还是喜欢用 python , java 的嗦简直不能忍 |
8 jjx 2015-11-02 12:13:02 +08:00 搞 python 的对这个已经麻木了 |
9 ilotuo 2015-11-02 12:15:32 +08:00 via Android 关键代码没写到 cpp 里 |
10 sunus 2015-11-02 12:18:31 +08:00 有可能是驱动的原因 |
11 wy315700 2015-11-02 12:22:14 +08:00 cpython 就是慢,然而 pypy 的内存占用太恐怖了 |
12 Comdex 2015-11-02 12:31:06 +08:00 go go go |
13 echo1937 2015-11-02 12:31:21 +08:00 不存在一种语言吃天下,所以该用什么语言的时候用什么语言。 不过你说的情况我怀疑是驱动的锅。 |
14 xunyu 2015-11-02 12:33:04 +08:00 via Android 可以试下 jython, |
15 tolbkni 2015-11-02 12:43:55 +08:00 试试换一个用 c 实现的 rabbitmq Python 库 |
17 timonwong 2015-11-02 13:02:31 +08:00 kombu + librabbitmq? pika 用默认的 blocking client 是超级慢,而且 bug 多。 |
18 ChanneW 2015-11-02 13:10:15 +08:00 show 代码 |
19 felixzhu 2015-11-02 13:20:55 +08:00 感觉你的这个场景应该不会有这么大差距,可否给个代码 |
20 ipconfiger 2015-11-02 13:28:20 +08:00 用 multiprocess 库 map 一下,起 100 个进程,很快就发完了 |
21 HentaiMew 2015-11-02 13:30:20 +08:00 py 性能若能跟 Java 比或者相提并论… 那它就是当之无愧的脚本之王了。。。 你是没见过速度慢上百倍的功能实现… 不过既然用 py 还在乎什么性能,就跟用 Java 还在乎什么内存一样 2333 |
22 love 2015-11-02 13:32:45 +08:00 py 虽慢,但象这么慢应该是你的问题。 |
23 virusdefender 2015-11-02 13:40:32 +08:00 要看应用场景了, Python 慢也可以写 c 语言补充部分实现。 |
24 eightqueen OP |
25 kmahyyg 2015-11-02 13:45:08 +08:00 表示 py 已经很快了,毕竟它没有编译成机器码直接执行,而是边解析边执行 速度和 java 一样的话, java 又臭又长的那些 classes 就可以去死了 |
26 zoowii 2015-11-02 14:06:23 +08:00 其实很多情况下可以忍的 不能忍再单独考虑嘛 |
27 shenqiu15 2015-11-02 14:08:32 +08:00 撸主真的有 50ms 推送 1000 条消息的需求吗? |
28 Mark24 2015-11-02 14:10:44 +08:00 速度和 Java 一样,你还能看到 Java ? |
29 yuelang85 2015-11-02 14:26:41 +08:00 py 确实比 java 慢。不过这个实验不太靠谱。 首先有个用法错误, for i in range(1000)应该换成 for i in orange 。 另外, py 里链接创建是 cOnnection= pika.BlockingConnection(pika.ConnectionParameters ,这个库的这个方法效率如何? 要比较语言性能,最好是不要用第三方库,纯粹做 数值运算一类的 |
30 weyou 2015-11-02 14:26:41 +08:00 就这两段代码看不出 python 能比 java 慢多少,感觉是 pika 库的设计出问题了。 |
31 eightqueen OP @shenqiu15 有啊,消费者是另一个家伙用 java 写的,他要求的 qps 是 2000 ,我发送消息只有 300 ,差太远啊 |
32 0987363 2015-11-02 14:29:01 +08:00 c 跟 go 表示 50ms 太慢 |
33 situs 2015-11-02 14:29:50 +08:00 1010 最快 你要写么? |
34 shenqiu15 2015-11-02 14:31:17 +08:00 @eightqueen 那就不要用 python 喽,没有一种语言能适用于所有场景。 |
35 eightqueen OP @yuelang85 orange 是什么东西?网上都查不到。 pika 是 rabbitmq 官网推荐的,我没得选。 |
36 hdjdcyl 2015-11-02 14:47:04 +08:00 PHP 是世界上最好的语言 |
37 yahoo21cn 2015-11-02 14:48:25 +08:00 java 用到多个 cpu 了吧, python 需要用 multiprocess 才能启用多 cpu ,速度就基本一样了 |
39 yuelang85 2015-11-02 15:09:30 +08:00 |
40 eightqueen OP @yuelang85 xrange 我测过,性能并没有提高,它是生成器,节约内存, 1000 条根本没关系。 |
41 mengzhuo 2015-11-02 15:37:56 +08:00 明显是 IO 型的程序,和语言几乎没啥关系, LZ 刚入行吧 上 gevent 或者 py3 的 async ,我们看看哪个厉害 |
42 mulog 2015-11-02 15:56:57 +08:00 没错 python 虽然是慢也不能什么锅都接啊。。 别的不说我复制楼主你的代码也跑不出 3s 这种水平啊 test_pyjava sudo rabbitmqctl list_queues Listing queues ... celery 0 task_queue 3000 ...done. test_pyjava py py.py 0.0359241962433 test_pyjava sudo rabbitmqctl list_queues Listing queues ... celery 0 task_queue 4000 ...done. test_pyjava py py.py 0.0347700119019 test_pyjava sudo rabbitmqctl list_queues Listing queues ... celery 0 task_queue 5000 ...done. |
43 clino 2015-11-02 16:07:42 +08:00 我觉得完全可以优化到差距不大的水平 for i in range(1000) 这个改成 xrange 先 |
44 marchon 2015-11-02 16:09:55 +08:00 41 楼说的才靠谱啊, io 型的任务肯定得用 gevent 之类 |
45 eightqueen OP |
46 clino 2015-11-02 16:16:01 +08:00 @eightqueen properties=pika.BasicProperties( delivery_mode = 2, # make message persistent ) 这个参数每次都是一样的吧? 你在 for 外面生成一个对象,然后每次直接传这个参数进去看看 |
47 geew 2015-11-02 16:25:34 +08:00 这种月经帖也是够了啊 先不说代码优化方面的问题 你说一个脚本语言和编译型语言有可比性吗.... |
48 eightqueen OP @clino 结果一样 |
49 clino 2015-11-02 16:33:56 +08:00 @eightqueen 那我觉得效率低的部分应该在你调用的 rabbitmq 的 python 库里,先不要那么怪 python 语言本身 |
50 lightening 2015-11-02 16:42:10 +08:00 你是 localhost 上 host 的 RabbitMQ 吗? 我们用的 Ruby ,应该是比 Python 还慢的。但是我们一秒钟能 push 7000 条信息,还带 ack 的。 |
51 mulog 2015-11-02 17:01:59 +08:00 @eightqueen 测给你看咯 test_pyjava py py.py 0.0353381633759 test_pyjava java -cp 'rabbitmq-java-client-bin-3.5.6/*:.' Producer 56 test_pyjava py py.py 0.0339579582214 test_pyjava java -cp 'rabbitmq-java-client-bin-3.5.6/*:.' Producer 56 test_pyjava py py.py0.0334329605103 test_pyjava java -cp 'rabbitmq-java-client-bin-3.5.6/*:.' Producer 55 都是你的代码 一行没改 rabbitmq 在本地跑 python 2.7.6 java version "1.7.0_76" |
52 eightqueen OP @mulog 见鬼了,为什么你这里 python 比 java 还快?改了什么代码吧。 |
53 harry890829 2015-11-02 17:17:06 +08:00 @sujin190 java 都嗦啊……那我这种写 c/c++的怎么办…… |
54 sujin190 2015-11-02 18:31:06 +08:00 @harry890829 java 的嗦不在于语言语法,而在于各种设计模式什么的滥用,用个 java ,光配置文件就看得头大。。 c/c++也可以写的很简练啊 |
55 harry890829 2015-11-02 18:55:49 +08:00 @sujin190 恩 c/c++确实可以写的很简练,主要是什么都要自己写,毕竟也是挺麻烦的 |
56 clino 2015-11-02 21:15:07 +08:00 用 https://docs.python.org/2/library/profile.html 在你的两个环境下都分析一下看看 |
57 imdoge 2015-11-02 22:14:33 +08:00 为什么在 leetcode 里,看运行时间 JAVA 运行时间才是最慢的? |
58 ethego 2015-11-02 22:16:04 +08:00 ``` zeno@go:~$ pypy test2.py 0.135266065598 zeno@go:~$ pypy test2.py 0.0797960758209 zeno@go:~$ pypy test2.py 0.0784769058228 zeno@go:~$ pypy test2.py 0.0792558193207 zeno@go:~$ pypy test2.py 0.131166934967 zeno@go:~$ pypy test2.py 0.0794620513916 zeno@go:~$ pypy test2.py 0.078901052475 zeno@go:~$ source venv/bin/activate (venv)zeno@go:~$ python test2.py 0.0328559875488 (venv)zeno@go:~$ python test2.py 0.0401589870453 (venv)zeno@go:~$ python test2.py 0.0292019844055 (venv)zeno@go:~$ python test2.py 0.0398349761963 (venv)zeno@go:~$ ``` |
60 Zzzzzzzzz 2015-11-02 22:26:17 +08:00 Jython 性能比 CPython 还烂。 range 和 xrange 在 1000 这个级别体现不出性能差, 相反小数组比起迭代来说不定 range 还会快点。 建议楼主 python 用多进程或者 gevent 的属于作弊, 毕竟顶楼那段 java 也没用 NIO 或者多线程。 单纯 IO 操作 PyPy 和 CPython 性能没太大差别, 有些时候 PyPy 还更慢点, CPython 和 Java 在运算上可能差很大, 但是 IO 操作上差距不会太大, 顶楼这个测试以 IO 为主, 差距这么大太不正常了, 建议跑一下 profile 在其他方面找找原因。 |
61 eightqueen OP @Zzzzzzzzz 谢谢,终于遇到个明白人 |
62 mengzhuo 2015-11-03 09:13:27 +08:00 via iPhone |
65 clino 2015-11-03 15:00:58 +08:00 @eightqueen profile 分析过了吗? 我很好奇是什么导致了你本地那么慢的 |
66 eightqueen OP @clino 0.0211880207062 1497 function calls (1482 primitive calls) in 0.022 seconds Ordered by: standard name ncalls tottime percall cumtime percall filename:lineno(function) 1 0.000 0.000 0.022 0.022 <string>:1(<module>) 1 0.000 0.000 0.022 0.022 Producer.py:17(send) 8 0.000 0.000 0.000 0.000 __init__.py:1130(debug) 1 0.000 0.000 0.000 0.000 __init__.py:1142(info) 9 0.000 0.000 0.000 0.000 __init__.py:1331(getEffectiveLevel) 9 0.000 0.000 0.000 0.000 __init__.py:1345(isEnabledFor) 1 0.000 0.000 0.000 0.000 _weakrefset.py:70(__contains__) 1 0.000 0.000 0.000 0.000 abc.py:128(__instancecheck__) 2 0.000 0.000 0.000 0.000 base_connection.py:141(_check_state_on_disconnect) 1 0.000 0.000 0.000 0.000 base_connection.py:333(_handle_read) 31 0.000 0.000 0.000 0.000 base_connection.py:354(_handle_write) 2 0.000 0.000 0.000 0.000 base_connection.py:368(_init_connection_state) 10 0.000 0.000 0.021 0.002 blocking_connection.py:1146(_send_method) 1 0.000 0.000 0.001 0.001 blocking_connection.py:198(close) 3 0.000 0.000 0.021 0.007 blocking_connection.py:234(process_data_events) 3 0.000 0.000 0.000 0.000 blocking_connection.py:249(process_timeouts) 10 0.000 0.000 0.021 0.002 blocking_connection.py:265(send_method) 2 0.000 0.000 0.000 0.000 blocking_connection.py:313(_adapter_disconnect) 3 0.000 0.000 0.000 0.000 blocking_connection.py:330(_deadline_passed) 3 0.000 0.000 0.021 0.007 blocking_connection.py:341(_handle_read) 2 0.000 0.000 0.000 0.000 blocking_connection.py:364(_check_state_on_disconnect) 34 0.000 0.000 0.000 0.000 blocking_connection.py:373(_flush_outbound) 1 0.000 0.000 0.000 0.000 blocking_connection.py:382(_on_connection_closed) 3 0.000 0.000 0.020 0.007 blocking_connection.py:39(inner) 31 0.000 0.000 0.021 0.001 blocking_connection.py:409(_send_frame) 10 0.000 0.000 0.021 0.002 blocking_connection.py:514(basic_publish) 3 0.000 0.000 0.020 0.007 blocking_connection.py:77(ready) 3 0.000 0.000 0.000 0.000 callback.py:114(add) 64 0.000 0.000 0.000 0.000 callback.py:14(_name_or_value) 1 0.000 0.000 0.000 0.000 callback.py:184(pending) 1 0.000 0.000 0.000 0.000 callback.py:199(process) 7 0.000 0.000 0.000 0.000 callback.py:235(remove) 2 0.000 0.000 0.000 0.000 callback.py:281(_arguments_match) 2 0.000 0.000 0.000 0.000 callback.py:302(_callback_dict) 7 0.000 0.000 0.000 0.000 callback.py:320(_cleanup_callback_dict) 1 0.000 0.000 0.000 0.000 callback.py:367(_should_process_callback) 1 0.000 0.000 0.000 0.000 callback.py:384(_use_one_shot_callback) 18/10 0.000 0.000 0.000 0.000 callback.py:47(wrapper) 14/7 0.000 0.000 0.000 0.000 callback.py:70(wrapper) 11 0.000 0.000 0.000 0.000 channel.py:566(is_open) 2 0.000 0.000 0.000 0.000 connection.py:1029(_has_open_channels) 1 0.000 0.000 0.000 0.000 connection.py:1039(_has_pending_callbacks) 2 0.000 0.000 0.000 0.000 connection.py:1049(_init_connection_state) 1 0.000 0.000 0.000 0.000 connection.py:1098(_is_connection_close_frame) 1 0.000 0.000 0.000 0.000 connection.py:1109(_is_method_frame) 1 0.000 0.000 0.000 0.000 connection.py:1272(_on_data_available) 1 0.000 0.000 0.000 0.000 connection.py:1309(_process_callbacks) 1 0.000 0.000 0.000 0.000 connection.py:1337(_process_frame) 1 0.000 0.000 0.000 0.000 connection.py:1367(_read_frame) 12 0.000 0.000 0.000 0.000 connection.py:1387(_remove_callback) 4 0.000 0.000 0.000 0.000 connection.py:1397(_remove_callbacks) 4 0.000 0.000 0.000 0.000 connection.py:1408(_remove_connection_callbacks) 1 0.000 0.000 0.000 0.000 connection.py:1414(_rpc) 1 0.000 0.000 0.000 0.000 connection.py:1441(_send_connection_close) 31 0.000 0.000 0.001 0.000 connection.py:1475(_send_frame) 11 0.000 0.000 0.021 0.002 connection.py:1494(_send_method) 4 0.000 0.000 0.000 0.000 connection.py:1521(_set_connection_state) 1 0.000 0.000 0.000 0.000 connection.py:1541(_trim_frame_buffer) 33 0.000 0.000 0.000 0.000 connection.py:746(is_closed) 2 0.000 0.000 0.000 0.000 connection.py:753(is_closing) 5 0.000 0.000 0.000 0.000 connection.py:760(is_open) 2 0.000 0.000 0.000 0.000 connection.py:841(_add_connection_start_callback) 1 0.000 0.000 0.000 0.000 connection.py:852(_append_frame_buffer) 1 0.000 0.000 0.000 0.000 connection.py:860(_buffer_size) 1 0.000 0.000 0.000 0.000 connection.py:900(_close_channels) 10 0.000 0.000 0.000 0.000 frame.py:118(__init__) 10 0.000 0.000 0.000 0.000 frame.py:128(marshal) 1 0.000 0.000 0.000 0.000 frame.py:192(decode_frame) 32 0.000 0.000 0.000 0.000 frame.py:20(__init__) 31 0.000 0.000 0.000 0.000 frame.py:30(_marshal) 12 0.000 0.000 0.000 0.000 frame.py:58(__init__) 11 0.000 0.000 0.000 0.000 frame.py:68(marshal) 10 0.000 0.000 0.000 0.000 frame.py:86(__init__) 10 0.000 0.000 0.000 0.000 frame.py:98(marshal) 1 0.000 0.000 0.000 0.000 socket.py:192(close) 31 0.000 0.000 0.000 0.000 socket.py:223(meth) 10 0.000 0.000 0.000 0.000 spec.py:1792(__init__) 10 0.000 0.000 0.000 0.000 spec.py:1828(encode) 1 0.000 0.000 0.000 0.000 spec.py:2481(__init__) 10 0.000 0.000 0.000 0.000 spec.py:2638(encode) 1 0.000 0.000 0.000 0.000 spec.py:387(__init__) 1 0.000 0.000 0.000 0.000 spec.py:414(encode) 1 0.000 0.000 0.000 0.000 spec.py:431(__init__) 1 0.000 0.000 0.000 0.000 spec.py:438(decode) 1 0.000 0.000 0.000 0.000 utils.py:8(is_callable) 116 0.000 0.000 0.000 0.000 {_struct.pack} 1 0.000 0.000 0.000 0.000 {_struct.unpack_from} 1 0.000 0.000 0.000 0.000 {_struct.unpack} 2 0.000 0.000 0.000 0.000 {any} 3 0.020 0.007 0.020 0.007 {built-in method poll} 32 0.000 0.000 0.000 0.000 {chr} 32 0.000 0.000 0.000 0.000 {getattr} 169 0.000 0.000 0.000 0.000 {isinstance} 64 0.000 0.000 0.000 0.000 {issubclass} 164 0.000 0.000 0.000 0.000 {len} 10 0.000 0.000 0.000 0.000 {math.ceil} 31 0.000 0.000 0.000 0.000 {method 'append' of 'collections.deque' objects} 89 0.000 0.000 0.000 0.000 {method 'append' of 'list' objects} 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} 21 0.000 0.000 0.000 0.000 {method 'insert' of 'list' objects} 31 0.000 0.000 0.000 0.000 {method 'join' of 'str' objects} 8 0.000 0.000 0.000 0.000 {method 'keys' of 'dict' objects} 31 0.000 0.000 0.000 0.000 {method 'popleft' of 'collections.deque' objects} 1 0.000 0.000 0.000 0.000 {method 'recv' of '_socket.socket' objects} 31 0.000 0.000 0.000 0.000 {method 'sendall' of '_socket.socket' objects} 10 0.000 0.000 0.000 0.000 {range} 6 0.000 0.000 0.000 0.000 {setattr} 5 0.000 0.000 0.000 0.000 {time.time} 就是 pika 库的问题啊,时间全耗在它上面了,不过为什么只在我本机才会出现这种情况,感觉没法分析啊。 |
67 clino 2015-11-03 17:06:06 +08:00 @eightqueen 会不会两边用的 pika 库版本不一样? git clone 个最新的试试看 |
68 eightqueen OP @clino 大神,终于被你猜对了,我本机用的 pika0.9 ,其他机器用的 0.10 ,我把本机升到最新,立马有了质的飞跃,太感谢了。 |