<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META content="text/html; charset=us-ascii" http-equiv=Content-Type>
<META name=GENERATOR content="MSHTML 8.00.6001.18999"></HEAD>
<BODY>
<DIV><SPAN class=268520505-16012011><FONT color=#000080 size=2 
face="Lucida Sans">I've noticed that RolapEvaluator.push() occurs a lot in 
computation-intensive queries, and it's not a cheap operation. Each evaluator 
contains 16 members, 5 of which are lists or arrays that need to be 
copied.</FONT></SPAN></DIV>
<DIV><SPAN class=268520505-16012011><FONT color=#000080 size=2 
face="Lucida Sans"></FONT></SPAN>&nbsp;</DIV>
<DIV><SPAN class=268520505-16012011><FONT color=#000080 size=2 
face="Lucida Sans">So, I'm thinking of changing the evaluator API. When you want 
to save a context, you would no longer create a copy of the evaluator. Instead 
you would create a savepoint that would allow the evaluator to roll back to its 
previous state.</FONT></SPAN></DIV>
<DIV><SPAN class=268520505-16012011><FONT color=#000080 size=2 
face="Lucida Sans"></FONT></SPAN>&nbsp;</DIV>
<DIV><SPAN class=268520505-16012011><FONT color=#000080 size=2 
face="Lucida Sans">RolapEvaluator.push() would no longer return a 
RolapEvaluator; it would return an int, the index on the stack of operations to 
roll back to. Operations that change the state of the evaluator would add a 
command to the stack to undo their effect. The stack would be a list of opcodes 
and arguments.</FONT></SPAN></DIV>
<DIV><SPAN class=268520505-16012011><FONT color=#000080 size=2 
face="Lucida Sans"></FONT></SPAN>&nbsp;</DIV>
<DIV><SPAN class=268520505-16012011><FONT color=#000080 size=2 
face="Lucida Sans">Currently if you call RolapEvaluator.push() you don't need to 
call pop(). The original evaluator is not modified, and when you finish using 
the new evaluator, the garbage collector will claim it eventually. After this 
change, every piece of code that calls push() will need to call 
RolapEvaluator.rollback(int savepoint). No question that this is more onerous 
and error-prone, but I think it's worth it.</FONT></SPAN></DIV>
<DIV><SPAN class=268520505-16012011><FONT color=#000080 size=2 
face="Lucida Sans"></FONT></SPAN>&nbsp;</DIV>
<DIV><SPAN class=268520505-16012011><FONT color=#000080 size=2 
face="Lucida Sans">There is another potentially major benefit. Another cost that 
shows up prominently in profiling is the cost of creating a CellRequest. Right 
now, each time you request a cell value, you need to build a cell request from 
scratch. Converting evaluator context to cell request is quite involved: you 
need to figure out the key columns of each member, a bitmap of those column ids, 
and build a list of the values of those columns. Not something one wants to do 
millions of times per query. To amortize that cost, I'd like to store 
partially-created cell requests in the evaluator, which would help because 
consecutive cell requests are often very similar. But to do that, I'd have to 
add a lot more state to the evaluator, and that would make it even more 
expensive to copy an evaluator.</FONT></SPAN></DIV>
<DIV><SPAN class=268520505-16012011><FONT color=#000080 size=2 
face="Lucida Sans"></FONT></SPAN>&nbsp;</DIV>
<DIV><SPAN class=268520505-16012011><FONT color=#000080 size=2 
face="Lucida Sans">With the proposed change to RolapEvaluator.push(), we would 
vastly reduce the number of times that we copy an evaluator, so we can build 
amortizing data structures that reduce the cost of requesting a cell from 
cache.</FONT></SPAN></DIV>
<DIV><SPAN class=268520505-16012011><FONT color=#000080 size=2 
face="Lucida Sans"></FONT></SPAN>&nbsp;</DIV>
<DIV><SPAN class=268520505-16012011><FONT color=#000080 size=2 
face="Lucida Sans">Anyone have any gut instinct on whether this change would be 
useful?</FONT></SPAN></DIV>
<DIV><SPAN class=268520505-16012011><FONT color=#000080 size=2 
face="Lucida Sans"></FONT></SPAN>&nbsp;</DIV>
<DIV><SPAN class=268520505-16012011><FONT color=#000080 size=2 
face="Lucida Sans">Julian</FONT></SPAN></DIV></BODY></HTML>