2014-01-24 28 views
0

這個問題與this有關,但是因爲我嘗試優化速度函數,所以我將這個問題作爲一個新問題提出。C#的Javascript端口BitConverter.DoubleToInt64Bits

我正在翻譯新的floats Clipper library從安格斯約翰遜到Javascript,並且有一個功能IsAlmostEqual,它使用Ulps技術比較雙等於平等。

原來的C#功能是在這裏:

 
public static bool IsAlmostEqual(double A, double B) 
{ 
    //http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm 
    const int maxUlps = 10000; 
    Int64 aInt = BitConverter.DoubleToInt64Bits(A); 
    if (aInt < 0) aInt = Int64.MinValue - aInt; 
    Int64 bInt = BitConverter.DoubleToInt64Bits(B); 
    if (bInt < 0) bInt = Int64.MinValue - bInt; 
    Int64 sub = unchecked(aInt - bInt); 
    if (sub > aInt != bInt < 0) return false; 
    return (sub <= 0 && sub > -maxUlps) || (sub > 0 && sub < maxUlps); 
} 

而且我對它的翻譯(在JSBIN):

 
var IsAlmostEqual_Ulps = function(A, B) 
{ 
    DoubleToInt64Bits(A, aInt); 
    if(aInt.hi < 0) aInt = subtract(Int64_MinValue, aInt); 
    DoubleToInt64Bits(B, bInt); 
    if(bInt.hi < 0) bInt = subtract(Int64_MinValue, bInt); 
    var sub = subtract(aInt, bInt); 
    if (sub.hi < 0) sub = negate(sub); 
    if (lessthan(sub, maxUlps)) return true; 
    return false; 
} 

我的JavaScript版本似乎根據83個樣本值到工作確定,但問題是緩慢,主要來自DoubleToInt64Bits函數。當代碼作爲獨立的html(JSBIN之外)執行時,總運行時間約爲2267毫秒,其中DoubleToInt64Bits需要983毫秒。

的問題(=慢)DoubleToInt64Bits是在這裏:

 
function DoubleToInt64Bits(A, xInt) 
{ 
    (new Float64Array(buf))[0] = A; 
    xInt.lo = (new Uint32Array(buf))[0] | 0; 
    xInt.hi = (new Int32Array(buf))[1] | 0; 
} 

有沒有什麼辦法讓DoubleToInt64Bits更快?

回答

1

A DataView是一個更合適的類,用於從緩衝區中讀出不同的類型,而不是在緩衝區上創建不同類型的數組。這裏是你的DoubleToInt64Bits方法改寫爲使用DataView

function DoubleToInt64Bits(A, xInt) 
{ 
    var dataView = new DataView(buf); 
    dataView.setFloat64(0, A); 
    xInt.lo = dataView.getUint32(4) | 0; 
    xInt.hi = dataView.getInt32(0) | 0; 
} 

這將我的運行時間從〜1500ms減少到〜850ms。

+0

非常感謝!在原始代碼中'DoubleToInt64Bits'需要800-1000毫秒。使用你的版本需要0-6毫秒。 –