ytyht226/taskflow

请教个问题

Closed this issue · 1 comments

DagEngine如果每次都是new一个,这样runAndWait都要解析下依赖,很多时候DagEngine的依赖关系都是确定的,
image

请问下这块从性能上考虑是不是有优化空间?

DagEngine如果每次都是new一个,这样runAndWait都要解析下依赖,很多时候DagEngine的依赖关系都是确定的, image

请问下这块从性能上考虑是不是有优化空间?

很好的问题,目前主要在建设引擎核心能力,节点依赖解析、引擎对象创建等是纯内存操作不是性能瓶颈,已经在规划一个对象池化的方案,这里可以先简单说下思路:
背景:
分析DAG编排流程后可以发现,每个节点包含两类对象:op(单例,程序运行时只有一份,对应的是节点的主逻辑)、wrapper(op的代理类,描述节点之间的依赖关系,用来串联起整个流程图,包含节点的依赖关系是有状态的,不可共享每个请求都需要单独创建);对于某一类业务流程,DAG图是固定的,不同的请求要执行的节点个数及先后顺序是固定的,不同的地方是请求初始参数,所以除了第一次请求之外,不用等到在处理每个请求时才创建DAG引擎、代理对象,可以提前创建并缓存;

对象个数:
创建编排流程对应的DAG图,在不考虑单例的op对象时,需要创建的对象个数如下 :
不存在节点组时:N + 1,N是节点个数,1是引擎;需要创建N个代理对象,1个引擎对象
存在节点组时:N + 3M + 1,N是节点个数,M是节点组个数,1是引擎;需要创建N个代理对象,3M个节点组包含的对象,1个引擎对象

对于某一类业务逻辑,N + 3M + 1个对象可以提前创建并缓存

方案选型:
方案一:对象复用
要点:
1、程序初始化时创建一定数量的对象并添加到对象池
2、程序运行过程中,优先从对象池获取对象,如果获取不到则创建新的对象
3、对象使用完之后通过后台线程将状态恢复到初始值,并重新添加到对象池
优点:对象直接从对象池获取可以做到完全复用,尽量减少对象的创建
缺点:
1、有状态的对象在使用完之后需要将状态恢复到初始值,如果对象的状态变量比较多,恢复时比较复杂,有可能造成遗漏,提交到线程池再次被重新使用时出现数据错乱
2、不容易扩展,如果对象增加了状态变量需要在恢复时也要添加相应的逻辑,容易遗漏
3、一个DAG图中节点比较多,如果有一个节点的状态恢复有问题,就会造成整个DAG图在执行时出现问题

方案二:对象预缓存
要点:
1、程序初始化时创建一定数量的对象并添加到对象池
2、程序运行过程中,优先从对象池获取对象,如果获取不到则创建新的对象
3、对象使用完之后直接回收掉
4、后台线程根据一定的策略(比如定时或者根据线程池中对象的数量)不断的创建新的对象并添加到对象池
优点:对象用完就回收,不需要考虑状态变量的恢复,容易扩展
缺点:
1、对象不能复用,需要有专门的线程持续的创建对象

最终方案:
DAG图中的节点依赖关系依据不同的场景可能非常复杂,引擎和代理类的状态变量比较多,恢复起来比较麻烦,考虑使用方案二