问题描述
客户在为BOM添加Item过程中自定义了一个UpdateTable Event事件,该事件需要对新加入的Item修改某些属性值,但发现每次添加一个Item,耗费好几秒才能完成,其中某一次性加入10个Item,共耗时40秒,性能极差。
分析
Agile PLM 9.3版本中为SDK开发引入了Event事件机制,可以让用户对具体的操作进行基于Java或Groovy的自定义的二次开发,大量拓展各种特殊的业务需求。该客户使用Java,基于Agile API的代码片段如下。public class UpdateBOMAttr implements IEventAction {
private static Integer ATT_READER = 2000008065;
private static Integer ATT_EDITOR = 2000008066;
public EventActionResult doAction(IAgileSession session,
INode actionNode, IEventInfo request) {
try {
IObjectEventInfo objectEventInfo = (IObjectEventInfo) request;
IDataObject affectedObject = objectEventInfo.getDataObject();
IItem item = (IItem)affectedObject;
Object reader = item.getValue(ATT_READER);
Object editor = item.getValue(ATT_EDITOR);
ITable bom = item.getTable(ItemConstants.TABLE_BOM);
Iterator cl = bom.getReferentIterator();
String nowTime=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new java.util.Date());
System.out.println(nowTime + " -- begin into while loop");
while (cl.hasNext()) {
IItem bomItem = (IItem)cl.next();
bomItem.setValue(ATT_READER, reader);
bomItem.setValue(ATT_EDITOR, editor);
nowTime=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new java.util.Date());
System.out.println(nowTime + " finished one Item --------------");
}
nowTime=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new java.util.Date());
System.out.println(nowTime + " -- done all");
ActionResult actionResult = new ActionResult(ActionResult.STRING, "ok_update attribute");
return new EventActionResult(request, actionResult);
} catch (Throwable th) {
ActionResult actionResult = new ActionResult(ActionResult.STRING, th.getMessage());
return new EventActionResult(request, null);
}
}
}
在while循环中,该程序需要对当前遍历的item设置两个属性bomItem.setValue。在客户的数据中中做测试后,查看打印信息
09/12/31 07:03:46 2009-12-31 07:03:46 -- begin into while loop
09/12/31 07:04:02 2009-12-31 07:04:02 finished one Item --------------
09/12/31 07:05:11 2009-12-31 07:05:11 finished one Item --------------
09/12/31 07:06:42 2009-12-31 07:06:42 finished one Item --------------
09/12/31 07:08:15 2009-12-31 07:08:15 finished one Item --------------
09/12/31 07:09:47 2009-12-31 07:09:47 finished one Item --------------
09/12/31 07:15:22 2009-12-31 07:15:22 finished one Item --------------
每个循环耗时1分30秒多。观察客户数据,原先BOM已有大量的Item。分析上述代码,会发现每次添加一个Item,代码均要扫描整个BOM表,为所有的Item都要重新设置一遍属性。代码逻辑冗余。
解决方法
在Agle API中,定义了专门针对新加入(或需要编辑的)的单独一行数据的类IEventDirtyRowUpdate,而引用此接口必须确保SDK得到的table也必须是实现了IEventDirtyTable接口的具体类。因此修改代码如下:public class UpdateBOMAttr implements IEventAction {
private static Integer ATT_READER = 2000008065;
private static Integer ATT_EDITOR = 2000008066;
public EventActionResult doAction(IAgileSession session,
INode actionNode, IEventInfo request) {
try {
// Get current Item's General Info attributes
IObjectEventInfo objectEventInfo = (IObjectEventInfo) request;
IDataObject affectedObject = objectEventInfo.getDataObject();
IItem item = (IItem) affectedObject;
Object reader = item.getValue(ATT_READER);
Object editor = item.getValue(ATT_EDITOR);
// get BOM table
IUpdateTableEventInfo eventInfo = (IUpdateTableEventInfo) request;
IEventDirtyTable table = eventInfo.getTable();
Iterator it = table.iterator();
String nowTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new java.util.Date());
System.out.println(nowTime + " -- begin into while loop");
// update the new BOM items
while (it.hasNext()) {
IEventDirtyRowUpdate row = (IEventDirtyRowUpdate) it.next();
IItem bomItem = (IItem)row.getReferent();
bomItem.setValue(ATT_READER, reader);
bomItem.setValue(ATT_EDITOR, editor);
nowTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new java.util.Date());
System.out.println(nowTime + " finished one Item --------------");
}
nowTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new java.util.Date());
System.out.println(nowTime + " -- done all");
ActionResult actionResult = new ActionResult(ActionResult.STRING, "ok_update attribute");
return new EventActionResult(request, actionResult);
} catch (Throwable th) {
ActionResult actionResult = new ActionResult(ActionResult.STRING, th.getMessage());
return new EventActionResult(request, null);
}
}
}
重新查看输出的信息:
10/02/26 02:34:02 2010-02-26 02:34:02 -- begin into while loop
10/02/26 02:34:02 2010-02-26 02:34:02 finished one Item --------------
10/02/26 02:34:03 2010-02-26 02:34:03 finished one Item --------------
10/02/26 02:34:03 2010-02-26 02:34:03 -- done all
经测试,一次性加入90个Item,只需要9秒即可执行完整个自定义的Event代码。