大数据量情况下,SPL 调用 java 自定义函数效率如何提高
目前,我们在客户实时项目的时候,我们经常有一些复杂逻辑的操作,势必要把这些复制逻辑写在一个自定义 java 类(该类的方法 reworkFilter 是静态方法)的函数中,然后通过 =invoke(..**.infrastructure.util.splFunction.SplFunc.reworkFilter,reworkName,isRework,reworkSeq, activitySeq, bv, ev);调用,当数据量很大时候,比如 1 亿条的时候,这个耗时 20,30 秒,严重影响性能,请问有什么其他方案可以替代吗?(spl 的 func 目前不考虑,希望用 java 类库的方案实现)
invoke 调用 java 静态方法已经无法优化过,没啥地方可以修正了
用户对性能要求很高,有其他代替方案吗?
1 亿条数据的转换成本(要转换成 Java 通行的数据类型后才能调用)就不会太低,这个函数要被执行多少次?它本身的执行性能如何?
invoke 通常只是解决一些 SPL 暂未提供的接口问题,纯运算逻辑最好全部写在 SPL 中。理论上 Java 代码速度更快,但大部分应用程序员不太会写基础的高性能算法,使用简单的慢算法常常会导致 Java 代码比 SPL 慢很多。
或者,读懂源代码,自己给 SPL 补个函数,在其中直接使用 SPL 已有的数据类型(不需要转换),还可能利用 SPL 类库中的算法。
或者自定义函数,也就是实现 Function 子类,具体参考http://d.raqsoft.com.cn:6999/esproc/manual/zdyhswj.html
主要是业务逻辑比较复杂,里面嵌套多个 for 循环,而且随着数量越大,性能可能越差,没有用到 spl 多核;只用到了 java stream.pallara() 多核并行,运行下来效果不理想,没有多大的速度提高。感觉 spl 调用自定义 java 函数,invoke 应该反射, 觉得是这块也耗时;这个函数是每行调用一遍,行数越多调用越多。
建议这么测试一下:
1. 把那个函数改成空的,直接 return,看看调用 1 亿次这个函数(含参数转换)所需要的时间,记为 T1
2. 函数的参数也删除,看看简单 invoke 1 亿次的时间,记为 T2
原来那个 20-30 秒记为 T0。
T0-T1 是这个函数本身执行 1 亿次的时间,T1-T2 是参数转换的时间
如果 T0-T1 太慢,这只能你自己优化这个函数了。T1-T2 太慢,可以考虑使用自定义函数,减少参数转换的时间。
按你的描述,里面还有多个 for 循环,我猜是 T0-T1 就很慢。
这种运算,如果能找到算法上的优化点,SPL 可能更快得多,而且也会比 Java 写起来简单得多。
invoke 就是首先找到 Method,然后在表达式计算时调用 Method.invoke,成本比 java 直接调用肯定高不少
有点搞不清你是怎么调用的,既然用 java Stream.parallel(),怎么又用到 spl 的 invoke 呢