插件函数的性能在计算一组向量时与内置函数几乎一样,但在分布式计算时为什么差了好多倍
我写了一个DolphinDB插件函数getBeta,实现的功能与内置函数beta一样。另外写了一个如下所示的向量化自定义函数:
def betaVec(x, y){
sumX = x.sum()
sumY = y.sum()
sumXY = sum(x*y)
sumX2 = sum(x*x)
n = x.size()
return (sumXY - sumX*sumY/n)/(sumX2 - sumX*sumX/n)
}
对一组1亿个元素的向量的进行计算:
x=rand(1.0, 100000000)
y=rand(1.0, 100000000)
timer(10) demo::getBeta(x,y) //2171ms
timer(10) beta(x, y) //2122ms
timer(10) betaVec(x, y) //7385ms
测试结果表明,内置函数和插件函数耗时基本相同,自定义函数耗时多3倍。
但是在DolphinDB database集群上对分布式表中一个月的股票行情数据进行计算:
db=database("dfs://STOCK_SHL2_TAQ")
t=db.loadTable("SHL2_TAQ")
timer data = select beta(close, low) as beta_u from t where date between 2020.06.01:2020.06.30 group by date, symbol, bar(time, 5)
//25,751 ms
timer data = select demo::getBeta(close, low) as beta_u from t where date between 2020.06.01:2020.06.30 group by date, symbol, bar(time, 5)
// 686,371 ms
timer data = select betaVec(close, low) as beta_u from t where date between 2020.06.01:2020.06.30 group by date, symbol, bar(time, 5)
//688,915ms
测试结果为:内置函数性能是插件函数的26倍。插件函数与自定义函数性能差不多。
我的问题就是:插件函数在计算一组向量时与内置函数几乎一样,但在分布式计算时为什么差了这么多倍?
下面附上我的插件代码,请大佬帮我看一下哪里有问题?
1.getBeta函数加在demo插件中,在src/demo.cpp中加入下面代码:
extern "C" ConstantSP getBeta(Heap* heap, vector<ConstantSP>& arguments );
2.在src/demo.cpp中加入下面代码:
ConstantSP beta(const ConstantSP& a, const ConstantSP& b){
INDEX len=std::min(a->size(),b->size());
INDEX obs=0;
double sumAB=0;
double sumA=0;
double sumB=0;
double sumB2=0;
double bufA[Util::BUF_SIZE];
double bufB[Util::BUF_SIZE];
const double* pa;
const double* pb;
INDEX start=0;
while(start<len){
int count=std::min(len-start,Util::BUF_SIZE);
pa=a->getDoubleConst(start,count,bufA);
pb=b->getDoubleConst(start,count,bufB);
for(int i=0;i<count;++i)
if(pa[i]!=DBL_NMIN && pb[i]!=DBL_NMIN){
sumB2+=pb[i]*pb[i];
sumAB+=pa[i]*pb[i];
sumA+=pa[i];
sumB+=pb[i];
++obs;
}
start+=count;
}
ConstantSP result(Util::createNullConstant(DT_DOUBLE));
if(obs >= 2){
double varB = sumB2-sumB*sumB/obs;
if(varB > 0)
result->setDouble((sumAB - sumA*sumB/obs)/varB);
}
return result;
}
ConstantSP getBeta(Heap* heap, vector<ConstantSP>& arguments ) {
std::string usage = "Usage:getBeta(x,y)";
if(!arguments[0]->isScalar() && !arguments[0]->isArray())
throw IllegalArgumentException(__FUNCTION__, usage + "x must be a scalar or vector.");
if(!arguments[1]->isScalar() && !arguments[1]->isArray())
throw IllegalArgumentException(__FUNCTION__, usage + "y must be a scalar or vector.");
return beta(arguments[0],arguments[1]);
}
3.在PluginDemo.txt中追加:
getBeta,getBeta,system,2,2,0
4.编译命令:
g++ -DLINUX -fPIC -std=c++11 -O3 -c src/Demo.cpp -I../include -o Demo.o
g++ -fPIC -shared -o libPluginDemo.so Demo.o -lDolphinDB -L /root/Downloads/v1.00.20/server
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
内置函数beta是一个聚合函数,在分布式表上,内置函数用的是分布式计算,而插件函数因为没有分布式计算,是把所有数据取到发起节点上来再计算,所以慢。若内置函数不是聚合函数,算法差不多时,它的性能与插件函数是一样。
插件开发教程第3节讲了如何开发用于处理分布式SQL的聚合函数,可参考教程把插件getBeta改成分布式聚合函数。