请选择 进入手机版 | 继续访问电脑版

石家庄老站长

点击联系客服
客服QQ: 客服微信:
 找回密码
 立即注册
查看: 3|回复: 0

11篇 HFM规则入门(4: For门深度浅)

[复制链接]

1

主题

1

帖子

-7

积分

限制会员

积分
-7
发表于 2021-7-22 00:18:11 | 显示全部楼层 |阅读模式
前面介绍了exp函数的使用。笔者建议读者仔细阅读官方文档对exp函数的经典使用。这个介绍h

调频

规则的For语句,f

Or

循环使用在所有语言中表达相同的意思。循环扫描集合是逻辑处理的。h

调频

规则也不例外。
1, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: 0.544px; orphans: 2; text-align: justify; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-style: initial; text-decoration-color: initial; line-height: normal; font-size: 10.5pt; font-family: 等线; text-indent: 21pt;">
For语句,笔者对它是又爱又恨,for语句实现逻辑简单明了,可读性强,是初学者的必然选择。但是For循环也是性能杀手,我们说HFM
运行计算或者合并耗时,产生性能问题,往往都是f
or
循环在作祟。但是有的场景,比如很多时候我们要扫码I
CP
维度时,就必须要用for循环,而且似乎没有可替代的优化手段。


一、for循环的简单应用

先来看下面的一段常规的for循环使用逻辑:

(图片可放大看)






解释上面这段逻辑:

1、首先规则一定要规范,比如规范的变量定义,初始化,以及必要的注释和语句的缩进。很多人刚开始学的时候不注意,规则写的非常的乱,一旦规则的堆积如山的时候,发现可读性极差,读者千万不要小看这些细节。良好的规范可以增强可读性,减少后期维护量以及供别人使用时能快速了解逻辑。

2、5050-5059行是对两个变量的定义以及初始化,其中strSourceMemeber是源POV,也即数据源,一般是各个维度的顶级成员(Total),strTargetMember01是目标POV,用来写数据的,各个维度的base成员([None])

3、5061-6064行是扫描AccountList这个父项的Base成员,然后进行计算前清数

4、5069-5084行,扫描ICP维度和科目维度进行了两层循环,将每个科目的每个ICP维度上的数据累加,放到ICP01这个ICP成员上

5、科目和ICP的设置如下:








二、for循环的优化

       上面这段逻辑通常我们都会用到,是规则实现的首选写法,也是初学者入门的学习路径,优点有很多:简单,易于理解,可读性强,方便维护。

但是弊端也很明显,假设,
AccountList
下面的成员有1000个,
[ICP Entities]
下面有5000个成员,那么双层循环扫描的代价就是:1000*5000的量级,也就是说不管科目与ICP维度的组合是否有数据,上面的逻辑都会扫描所有科目和所有ICP成员,这样就会消耗系统大量资源,尤其在高并发的场景时,会产生性能问题,导致系统运行缓慢,甚至卡死。

       针对上面这种写法,我们常用的一种优化方式就是使用HFM提供的OpenDataUnit函数,这也是进阶写法。

改进后的写法如下:




我们仍然作几点解释:

1)1772-1783行与前面逻辑一致,不做赘述

2)1786行使用了HFM内置函数OPENDATAUNIT进行结果集的获取,对于单个维度成员引用直接使用”短名称#维度成员”即可,但是对于维度集合的使用,必须用大括号,如科目:A{AccountList.[Base]}这样的写法。这么写的优点就是一次性将有数据的科目和ICP过滤出来,维度组合上没有数据的不会出现在结果集中。这样就大大减少了集合的数量级。

3)1788-1800行就是对有数据的组合进行使用,比如我们可以只处理dData0的数据


三、结论

1)、如果想要写出高效的规则,非常建议使用HFM内置的函数。具体可参考官方文档中的规则函数部分。

2)、对于初学者来说,规则入门建议从for循环这种基本写法开始,后续再根据情况升级写法。

3)、前面提到for循环有优点,也有缺点,需要根据具体情况针对使用,有的业务场景必须要用for循环,使用如opendataunit函数是不能代替的,读者试想下,哪种情况是for循环不能被代替的?


四、有关OpenDataUnit的思考

1)使用OpenDataUnit函数代替可以大幅提升规则效率,尤其是在科目和ICP量级比较大的时候,效率可提升50%+,具体可根据实际情况进行测试。

2)OpenDataUnit的底层应该是将POV组合条件在数据库中将查询出有数据的组合,然后将结果集返回,最后去扫描结果集进行逻辑处理。而不像for循环一样,需要逐条去读取数据库的数据。

3)OpenDataUnit函数中,假设以科目为例,当使用
A{AccountList.[Children]}时,意思是取AccountList的直接子代,结构如下:





A{AccountList.[Children]}
成员列表,获取的结果是:122101,122102,
122103
,122104,122105,其中
122103
是一个父级科目。
当我们使用如下语句:Dataunit.item(i).Account时是获取不到
122103
这个科目的






笔者以前没有注意过这个现象,读者可去试试,欢迎来讨论结果。

所以笔者认为用成员列表获取数据时是只能读取base级别,在OpenDataUnit中如果使用了成员列表,取到的是base数据,想要获取父级数据,要用A#122103单个科目的写法。

4、最后总结还是这一句,读者看5句,不如亲自去实践,写一句看现象,输出结果,相信必有所获,掌握其中的真谛与设计意图。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|无图版|手机版|小黑屋|石家庄@IT精英团

GMT+8, 2021-8-5 12:25 , Processed in 0.202800 second(s), 27 queries .

Powered by Discuz! X3.4

© 2001-2021 Comsenz Inc.

快速回复 返回顶部 返回列表