2017-09-15 189 views
0

我正在嘗試編寫一篇關於我在javascript中編寫和編碼的算法的科學文章。我希望能夠比較舊的緩慢版本與新版本的快速版本,並能夠報告一些指標,如調用Math.log的次數,調用Math.exp的次數,乘法操作的次數,除法運算的數量,增加的數量,增減數量等在javascript中計算浮點運算的次數

我意識到,JavaScript引擎的JIT編譯器可以做一些優化,改變這些數字有點,但我真的不關心確切每個指標的詳細信息,但僅限於我將這兩種算法中的蘋果與蘋果進行比較。

是否有任何工具或方法在JavaScript中自動計算這些操作?是否有任何JavaScript引擎會生成某種類型的中間字節碼,以便自動計算這些操作?如果不是JavaScript,那麼在C++中呢?

+0

Chrome可能會在其個人資料結果中顯示調用'Math.x'的次數。 –

+0

Javascript允許你重新定義內置的方法。例如 - >'var oLog = Math.log; Math.log =(x)=> {console.log('log');返回oLog(x); }'會輸出'log'並返回原始日誌。所以如果你沒有太多的功能你想分析,這個簡單的方法可能會做。 – Keith

回答

1

下面是一個非常簡單的例子,它包裝原始Math.sin & Math.log,並保持對調用的計數。

這工作,因爲在Javascript中,你甚至有權力更換內置的..

let counts = {}; 
 

 
function profileProc(root, name, proc) { 
 
    let oProc = proc; 
 
    root[name] = function() { 
 
    counts[name] = counts[name] ? counts[name] + 1 : 1; 
 
    return oProc.apply(proc, arguments); 
 
    } 
 
} 
 

 
profileProc(Math, 'log', Math.log); 
 
profileProc(Math, 'sin', Math.sin); 
 

 
console.log(Math.log(10)); 
 
console.log(Math.sin(10)); 
 
console.log(Math.sin(20)); 
 

 
console.log(counts);

+0

謝謝,我一定會將它用於Math.x函數。儘管如此,我更擔心基本的*/+操作。任何想法這些? – bruceceng

0

嗯,它看起來像我發現一些作品。作爲paper.js的一部分,存在一種稱爲PaperScript的腳本語言,它解析用JavaScript語法編寫的代碼並添加運算符重載,如解釋here所述。基本上paper.js提供paper.PaperScript.compile(code)函數採用JavaScript代碼和與呼叫來替換每一個數學運算以

function __$__(left, operator, right) {...} 

所以像變種var c = a * b;的表達變得var c = __$__(a, '*', b);一旦這個變換製成,它是簡單的修改__$__功能在爲了計數操作:

window.operatorCounts = {}; 
window.operatorCounts['+'] = 0; 
window.operatorCounts['-'] = 0; 
window.operatorCounts['*'] = 0; 
window.operatorCounts['/'] = 0; 
window.operatorCounts['%'] = 0; 
window.operatorCounts['=='] = 0; 
window.operatorCounts['!='] = 0; 

function __$__(left, operator, right) { 
    window.operatorCounts[operator]++; 
    switch (operator) { 
    case '+': return left + right; 
    case '-': return left - right; 
    case '*': return left * right; 
    case '/': return left/right; 
    case '%': return left % right; 
    case '==': return left == right; 
    case '!=': return left != right; 
    default: 
    throw new Error('Implement Operator: ' + operator); 
    } 
}; 

運營商的這種Instrumented版本確定後,這是一個簡單的事情,運行新的編譯功能。通過將這與Keith對Math.x函數的回答結合起來,我能夠完成我設定的任務。