[Mondrian] Some optimizations based on profiler results

Ajit Vasudeo Joglekar ajogleka at thoughtworks.com
Thu Oct 18 08:36:13 EDT 2007


We did some profiling on mondrian code base. We have a large catalog with 
hundreds of dimensions and measures. Based on the hotspots identified by 
the profiler here are some optimizations that make considerable difference 
in performance in the evaluation of a single mdx.

We would like to introduce these changes. Inviting comments, suggestions

Thanks,
-Ajit, Ashwin

===================

1) In RolapCubeSchemaReader we have a getCalculatedMembers method that 
creates a new list of calculated members based on the role configured in 
the Mondrian schema.

In the scenario where we have a huge number of calculated members and no 
Role configured this operation becomes quite expensive on multiple 
invocations.

We can fix this by returning the original list of calculated members if 
the access is the default access

 public List<Member> getCalculatedMembers() {
            List<Member> list = new ArrayList<Member>();
                       for (Formula formula : calculatedMembers) {
                                 Member member = formula.getMdxMember();
                                 if (getRole().canAccess(member)) {
                                     list.add(member);
                                 }
                             }
            return list;
        }
 
        becomes
 
         public List<Member> getCalculatedMembers() {
                if(Access.ALL == getRole().getAccess()){
                        return calculatedMembers; // indicative - need to 
convert [] to list. one option is We can maintain ArrayList and return [] 
where ever necessary
                }
 
                List<Member> list = new ArrayList<Member>();
                     for (Formula formula : calculatedMembers) {
                         Member member = formula.getMdxMember();
                         if (getRole().canAccess(member)) {
                             list.add(member);
                         }
                     }
            return list;
        }
 
2) In the RolapMember equals method :

        private boolean equals(RolapMember that) {
                assert that != null; 
 
                return this.getUniqueName().equals(that.getUniqueName());
    }
 
    Now if the assert fails it will throw an exception which means equals 
will fail with a non boolean value which should not happen and assert is 
an expensive operation 
    when compared to a null check.
 
    it can be changed to:
 
        private boolean equals(RolapMember that) {
                if(that == null){
                        return false;
                }
 
                return this.getUniqueName().equals(that.getUniqueName());
    }
 
3) In RolapEvaluator :
 public final Member setContext(Member member) {
        final RolapMember m = (RolapMember) member;
        final int ordinal = m.getDimension().getOrdinal(root.cube);
        final Member previous = currentMembers[ordinal];
 
        if (previous.isCalculated()) {
            removeCalcMember(previous);
        }
        currentMembers[ordinal] = m;
        if (m.isCalculated()) {
            addCalcMember(m);
        }
        return previous;
    }
 
    now we can optimize this by adding an equals to verify that m and 
previous are not the same.
 
     public final Member setContext(Member member) {
            final RolapMember m = (RolapMember) member;
            final int ordinal = m.getDimension().getOrdinal(root.cube);
            final Member previous = currentMembers[ordinal];
            if (m.equals(previous))
                return previous;
            if (previous.isCalculated()) {
                removeCalcMember(previous);
            }
            currentMembers[ordinal] = m;
            if (m.isCalculated()) {
                addCalcMember(m);
            }
            return previous;
    }
 
    this reduces some operations in case of massive number of invocations 
to this method.

===================
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.pentaho.org/pipermail/mondrian/attachments/20071018/72a4233f/attachment.html 


More information about the Mondrian mailing list