2012年9月19日 星期三

JForthBlocks--測試有無DoLit的效能

在Forth裡DoLit指令是用來取字面值(literal)的巧妙機制,當定義高階詞時,如有字面值(literal)編入詞典時,會同時夾帶DoLit編入字面值(literal)的前一個位址,如此一來,當Forth執行到DoLit指令時,便會自動取下一個位址的字面值(literal),這技巧在以低階語言開發的Forth系統上很有效率

不過,JForthBlocks所依賴的以Javascript開發的JeForth,DoLit是否還保有同樣的優勢?

Jimmy's papa動手修改JeForth部份程式碼,再用JForthBlocks同一份積木程式,測試看看有無DoLit的效能,是否有很大的差異,底下是跑五百萬次迴圈的輸出結果,第一次跑出的結果,有無DoLit指令似乎只有幾百微秒(milliseconds)的差異,隨後兩次的結果,執行時間會爆增,或許是垃圾收集機制的干擾

首先,測試compilecode('doLit',n)的效能
        function call(xt){// high level definition inner execution loop
            highLevelLooping=true; ip=xt;
            do{
                var id=dictionary[ip++];
                //if(typeof(id)=='object'){var v=id['lit'];stack.push(v);continue;}
                ........
                ........            
            }
        }

        function exec(src){ //source code interpreting loop
            .....
            .....
            do{token=nexttoken(); word=token;
                var id=findword(token);
                ......
                ......    
                       if(typeof(n)==='string'||n<=0||n>0){
                        if(compiling)
                            compilecode('doLit',n);// compile an literal
                            //compilecode({lit : n});
                ......
                ......
            }while(error===0&&ntib<tib.length);}

          }
寄件者 scratchlab02
連續執行三次的結果




再來,測試compilecode({lit : n})的效能,執行時則統一由call(xt)代勞取字面值(literal)
        function call(xt){// high level definition inner execution loop
            highLevelLooping=true; ip=xt;
            do{
                var id=dictionary[ip++];
                if(typeof(id)=='object'){var v=id['lit'];stack.push(v);continue;}
                ........
                ........            
            }
        }

        function exec(src){ //source code interpreting loop
            .....
            .....
            do{token=nexttoken(); word=token;
                var id=findword(token);
                ......
                ......    
                       if(typeof(n)==='string'||n<=0||n>0){
                        if(compiling)
                            //compilecode('doLit',n);// compile an literal
                            compilecode({lit : n});
                ......
                ......
            }while(error===0&&ntib<tib.length);}

          }
寄件者 scratchlab02
連續執行三次的結果,看來三戰兩勝,以微幅差距領先



底下是積木的XML,可以貼到JForthBlocks的XML編輯區,便會將這次測試所用到的積木載入
<xml xmlns="http://www.w3.org/1999/xhtml">
  <block type="procedures_defnoreturn" notchtype="Top_Bottom_Right" inline="false" x="137" y="55">
    <title name="NAME">TestLiteral</title>
    <statement name="STACK">
      <block type="math_PushNumber" notchtype="TOP_BOTTOM">
        <title name="NUM">5000000</title>
        <next>
          <block type="control_ForNext" notchtype="Top_Bottom_Right" inline="false">
            <statement name="STACK">
              <block type="math_PushNumber" notchtype="TOP_BOTTOM_RIGHT" inline="false">
                <title name="NUM">0</title>
                <value name="NEXTWORD">
                  <block type="math_PushNumber" notchtype="LEFT_RIGHT" inline="false">
                    <title name="NUM">0</title>
                    <value name="NEXTWORD">
                      <block type="stack_2drop" notchtype="LEFT_RIGHT" inline="false"></block>
                    </value>
                  </block>
                </value>
                <next>
                  <block type="math_PushNumber" notchtype="TOP_BOTTOM_RIGHT" inline="false">
                    <title name="NUM">0</title>
                    <value name="NEXTWORD">
                      <block type="math_PushNumber" notchtype="LEFT_RIGHT" inline="false">
                        <title name="NUM">0</title>
                        <value name="NEXTWORD">
                          <block type="stack_2drop" notchtype="LEFT_RIGHT" inline="false"></block>
                        </value>
                      </block>
                    </value>
                  </block>
                </next>
              </block>
            </statement>
          </block>
        </next>
      </block>
    </statement>
  </block>
  <block type="utility_milliseconds" notchtype="LEFT_RIGHT" inline="false" x="89" y="289">
    <value name="NEXTWORD">
      <block type="procedures_callnoreturn" notchtype="LEFT_RIGHT" inline="false">
        <mutation name="TestLiteral"></mutation>
        <value name="NEXTWORD">
          <block type="utility_milliseconds" notchtype="LEFT_RIGHT" inline="false">
            <value name="NEXTWORD">
              <block type="stack_swap" notchtype="LEFT_RIGHT" inline="false">
                <value name="NEXTWORD">
                  <block type="math_Minus" notchtype="LEFT_RIGHT" inline="false">
                    <value name="NEXTWORD">
                      <block type="print_DotS" notchtype="LEFT_RIGHT" inline="false"></block>
                    </value>
                  </block>
                </value>
              </block>
            </value>
          </block>
        </value>
      </block>
    </value>
  </block>
</xml>

沒有留言:

張貼留言