Python与JAVA仿三菱PLC的性能比较

测试背景是一款自动化软件平台上的逻辑模块性能对比。能够实现复杂逻辑的目前有结构化文本(指令表)和Python(Jython)两个。

三菱指令的解释器是原创的,因为没有相关的Java支持。Python程序的解释器是Jython2.7.2。

由于功能等级不同,三菱指令的编译时间较快,对程序的修改是无缝接入的。Jython的compile函数调用时间约5秒,但可以使用Python的高级功能。实际运行时不再编译,所以这个时间没有测。

编译完成后运行几分钟后,对逻辑区的运行时间进行测量,排除内部IO区的干扰(例程无物理IO)后,对程序进行修改,使运行时间接近。所需时间最小值为0.013ms时,两者的程序片段如下:

Python:

D[11] = random.randrange(10)
D[12] = 2
D[13] = 3

三菱Q系列指令:

0	LDI T1023
1	OUT T1023 K1
5	INV
6	OUT M61439
7	LDP M61439
8	OUT M61436
9	INC D20475
11	LD SM400
12	/ D20475 K10 D20469
15	MOV D20470 D20475
17	LD M61439
18	AND= D20475 K0
21	INV
22	CJ P4096
24	LD SM400
25	+ K1 D20477
28	/ D20477 K16 D20467
31	MOV D20468 D20477
33	P4096
34	LD<= D20477 K8
37	CJ P4097
39	LD SM400
40	- K16 D20477 D20476
43	JMP P4098
45	P4097
46	LD SM400
47	MOV D20477 D20476
49	P4098
50	LD<> D20476 K0
53	CJ P4099
55	LD SM400
56	MOV K1 D0
58	MOV K1 D1
60	MOV K0 D2
62	JMP P4100
64	P4099
65	LD<> D20476 K1
68	CJ P4101
70	LD SM400
71	MOV K1 D0
73	/ D0 K2 D20465
76	MOV D20465 D0
78	MOV K1 D1
80	MOV K0 D2
82	JMP P4100
84	P4101
85	LD<> D20476 K2
88	CJ P4102
90	LD SM400
91	MOV K0 D0
93	MOV K1 D1
95	MOV K0 D2
97	JMP P4100
99	P4102
100	LD<> D20476 K3
103	CJ P4103
105	LD SM400
106	MOV K0 D0
108	MOV K1 D1
110	/ D1 K2 D20465
113	MOV D20465 D1
115	MOV K0 D2
117	JMP P4100
119	P4103
120	LD<> D20476 K4
123	CJ P4104
125	LD SM400
126	MOV K0 D0
128	MOV K0 D1
130	MOV K0 D2
132	JMP P4100
134	P4104
135	LD<> D20476 K5
138	CJ P4105
140	LD SM400
141	MOV K0 D0
143	MOV K-1 D1
145	/ D1 K2 D20465
148	MOV D20465 D1
150	MOV K1 D2
152	/ D2 K2 D20465
155	MOV D20465 D2
157	JMP P4100
159	P4105
160	LD<> D20476 K6
163	CJ P4106
165	LD SM400
166	MOV K0 D0
168	MOV K-1 D1
170	MOV K1 D2
172	JMP P4100
174	P4106
175	LD<> D20476 K7
178	CJ P4107
180	LD SM400
181	MOV K1 D0
183	/ D0 K2 D20465
186	MOV D20465 D0
188	MOV K-1 D1
190	MOV K1 D2
192	JMP P4100
194	P4107
195	LD<> D20476 K8
198	CJ P4108
200	LD SM400
201	MOV K1 D0
203	MOV K-1 D1
205	MOV K1 D2
207	JMP P4100
209	P4108
210	LD SM400
211	MOV K1 D0
213	MOV K1 D1
215	MOV K1 D2
217	P4100
218	LD= D0 K1
221	AND= D1 K1
224	AND= D2 K0
227	CJ P4109
229	LD= D0 K0
232	AND= D1 K1
235	AND= D2 K0
238	CJ P4111
240	LD= D0 K0
243	AND= D1 K0
246	AND= D2 K0
249	CJ P4112
251	LD= D0 K0
254	AND= D1 K-1
257	AND= D2 K1
260	CJ P4113
262	LD= D0 K1
265	AND= D1 K-1
268	AND= D2 K1
271	CJ P4114
273	LD SM400
274	MOV K-1 D3
276	JMP P4110
278	P4114
279	LD SM400
280	MOV K1 D3
282	JMP P4110
284	P4113
285	LD SM400
286	MOV K2 D3
288	JMP P4110
290	P4112
291	LD SM400
292	MOV K3 D3
294	JMP P4110
296	P4111
297	LD SM400
298	MOV K4 D3
300	JMP P4110
302	P4109
303	LD SM400
304	MOV K5 D3
306	P4110
307	LD M61439
308	INC D20474
310	LD SM400
311	/ D20474 K10 D20469
314	MOV D20470 D20474
316	LD= D20474 K0
319	OUT M61438
320	LDP M61438
321	OUT M61437
322	LD M61437
323	RND D11
325	LD M61437
326	RND D12
328	LD M61437
329	RND D13
331	LD M61437
332	RND D21
334	LD M61437
335	RND D22
337	LD M61437
338	RND D23
340	LDI M61437
341	CJ P4115
343	LD SM400
344	MOV K100 D20473
346	* D20473 K100 D20467
349	MOV D20467 D20473
351	MOV K1000 D20472
353	MOV K10 D20471
355	/ D11 D20473 D20467
358	/ D20468 D20472 D20465
361	MOV D20465 D11
363	/ D12 D20473 D20465
366	/ D20466 D20472 D20463
369	MOV D20463 D12
371	/ D13 D20473 D20463
374	/ D20464 D20472 D20461
377	MOV D20461 D13
379	/ D21 D20473 D20461
382	/ D20462 D20471 D20459
385	MOV D20459 D21
387	/ D22 D20473 D20459
390	/ D20460 D20471 D20457
393	MOV D20457 D22
395	/ D23 D20473 D20457
398	/ D20458 D20471 D20455
401	MOV D20455 D23
403	P4115

这段汇编对应的源程序如下:

(* 平台程序 *)
globalTicker_1();
梯形图主程序_1();
(* 业务程序 *)

一次方案流水灯_1(MAIN_SWITCH:= D0 ,
		DISCONNECTOR_SWITCH:= D1 ,
		EARTH_SWITCH:= D2 ,
		STATE_DESCRIPTION:= D3 );

一次方案随机数_1(I_A:= D11 ,
		I_B:= D12 ,
		I_C:= D13 ,
		U_A:= D21 ,
		U_B:= D22 ,
		U_C:= D23 );


=================================================

(*流水灯*)

INC(LDP(1,G_SYSTEMTICK) , TICK_COUNTER);
TICK_COUNTER := TICK_COUNTER MOD 10;

IF G_SYSTEMTICK AND (TICK_COUNTER = 0) THEN
	ENGINE := ENGINE + 1;
	ENGINE := ENGINE MOD 16;
END_IF;

IF ENGINE <= 8 THEN
	STATE := ENGINE;
ELSE
	STATE := 16 - ENGINE;
END_IF;

CASE STATE OF
	0:
	MAIN_SWITCH := 1;
	DISCONNECTOR_SWITCH := 1;
	EARTH_SWITCH := 0;
	1:
	MAIN_SWITCH := 1;MAIN_SWITCH := MAIN_SWITCH / 2;
	DISCONNECTOR_SWITCH := 1;
	EARTH_SWITCH := 0;
	2:
	MAIN_SWITCH := 0;
	DISCONNECTOR_SWITCH := 1;
	EARTH_SWITCH := 0;
	3:
	MAIN_SWITCH := 0;
	DISCONNECTOR_SWITCH := 1;DISCONNECTOR_SWITCH := DISCONNECTOR_SWITCH / 2;
	EARTH_SWITCH := 0;
	4:
	MAIN_SWITCH := 0;
	DISCONNECTOR_SWITCH := 0;
	EARTH_SWITCH := 0;
	5:
	MAIN_SWITCH := 0;
	DISCONNECTOR_SWITCH := -1;DISCONNECTOR_SWITCH := DISCONNECTOR_SWITCH / 2;
	EARTH_SWITCH := 1;EARTH_SWITCH := EARTH_SWITCH / 2;
	6:
	MAIN_SWITCH := 0;
	DISCONNECTOR_SWITCH := -1;
	EARTH_SWITCH := 1;
	7:
	MAIN_SWITCH := 1;MAIN_SWITCH := MAIN_SWITCH / 2;
	DISCONNECTOR_SWITCH := -1;
	EARTH_SWITCH := 1;
	8:
	MAIN_SWITCH := 1;
	DISCONNECTOR_SWITCH := -1;
	EARTH_SWITCH := 1;
	ELSE
	MAIN_SWITCH := 1;
	DISCONNECTOR_SWITCH := 1;
	EARTH_SWITCH := 1;
END_CASE;

IF MAIN_SWITCH = 1
	AND DISCONNECTOR_SWITCH = 1
	AND EARTH_SWITCH = 0 THEN
	STATE_DESCRIPTION := 5;
ELSIF MAIN_SWITCH = 0
	AND DISCONNECTOR_SWITCH = 1
	AND EARTH_SWITCH = 0 THEN
	STATE_DESCRIPTION := 4;
ELSIF MAIN_SWITCH = 0
	AND DISCONNECTOR_SWITCH = 0
	AND EARTH_SWITCH = 0 THEN
	STATE_DESCRIPTION := 3;
ELSIF MAIN_SWITCH = 0
	AND DISCONNECTOR_SWITCH = -1
	AND EARTH_SWITCH = 1 THEN
	STATE_DESCRIPTION := 2;
ELSIF MAIN_SWITCH = 1
	AND DISCONNECTOR_SWITCH = -1
	AND EARTH_SWITCH = 1 THEN
	STATE_DESCRIPTION := 1;
ELSE
	STATE_DESCRIPTION := -1;
END_IF;

===============================================

(*随机数:*)

INC(G_SYSTEMTICK,TICKER_COUNTER);
TICKER_COUNTER := TICKER_COUNTER MOD 10;
TIMER_SIGNAL := TICKER_COUNTER = 0;
TIMER_SIGNAL_P := LDP(TRUE,TIMER_SIGNAL) ;

RND( TIMER_SIGNAL_P , I_A );
RND( TIMER_SIGNAL_P , I_B );
RND( TIMER_SIGNAL_P , I_C );
RND( TIMER_SIGNAL_P , U_A );
RND( TIMER_SIGNAL_P , U_B );
RND( TIMER_SIGNAL_P , U_C );

IF TIMER_SIGNAL_P THEN
	RAND_LIMIT := 1000;
	RAND_LIMIT := RAND_LIMIT * 100;
	I_DECS := 1000;
	U_DECS := 10;
	
	I_A := I_A MOD RAND_LIMIT / I_DECS;
	I_B := I_B MOD RAND_LIMIT / I_DECS;
	I_C := I_C MOD RAND_LIMIT / I_DECS;
	U_A := U_A MOD RAND_LIMIT / U_DECS;
	U_B := U_B MOD RAND_LIMIT / U_DECS;
	U_C := U_C MOD RAND_LIMIT / U_DECS;
END_IF;

可以看到同样的时间三菱Q系列解释器可以比Python做更多的事情,就随机数的使用上,这些时间内Python只能做一次随机数,Q系列解释器可以调用6次随机数还能加一大堆别的事情。

测试只测展示出的这一段,Python对程序大小也比较敏感,把那个随机数的函数拿掉就会快一些。Python的程序规模大一点耗时就超过了1ms,而同样的事情Q系列指令解释器只需要0.02~0.08ms。结构化文本和梯形图的学习难度也小于Python,最终推荐用于自动化逻辑脚本编程的是结构化文本和梯形图,Python作为一种附加接口模块,用于通讯、文件处理等功能的二次开发。

续:

后来我又测试了不用库函数的程序,发现如果不用库函数的话,Python是可以和Java一比的,Python的性能主要是消耗在库函数上。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值