簡體   English   中英

為什么Java本機緩沖區變慢?

[英]Why are Java native buffers that slow?

我試圖優化在Android設備上運行的簡單區域增長算法。 最初,我使用ArrayList來保存屬於一個區域的點。 每個點都由Point實例描述,每個實例都需要實例化。 該算法花了大約15秒的時間才能找到圖像中約1兆像素的所有區域。

Point類很簡單:

class Point
{
    public int x, y;
}

我以為我可以通過減少Point實例化的次數來減少計算時間。 因此,我用Region類替換了點列表,該類利用本地緩沖區進行點登記:

private int capacity;
private int pointsCount = 0;

private ByteBuffer buffer;
private IntBuffer intBufferView;

根據點數計算所需的字節緩沖區大小:

private static int getByteBufferSize( int capacity )
{
    // 4 bytes per integer and 2 integers per point
    return capacity * 4 * 2;
}

我選擇的初始容量為100,但我也嘗試將其設置為10,這是ArrayList的初始容量,然后嘗試將其設置為測試圖像中最大區域的大小:

public Region()
{
    this.capacity = 100;
    this.buffer = ByteBuffer.allocateDirect( getByteBufferSize( 100 ) );
    this.intBufferView = buffer.asIntBuffer();
}

為了向該區域添加點,我使用了以下方法:

public void add( final Point point )
{
    if( pointsCount >= capacity )
    {
        grow();
    }

    final int offset = 2 * pointsCount;
    intBufferView.put( offset + 0, point.x );
    intBufferView.put( offset + 1, point.y );
    ++pointsCount;
}

為了讀取由索引標識的特定點,此方法:

public void fetchPoint( Point p, int pointIndex )
{
    final int offset = 2 * pointIndex;
    p.x = intBufferView.get( offset + 0 );
    p.y = intBufferView.get( offset + 1 );
}

我實現了與ArrayList所使用的策略相等的增長策略:

private void grow()
{
    capacity = ( capacity * 3 ) / 2 + 1;
    final int bufferSize = getByteBufferSize( capacity );
    final ByteBuffer newBuffer = ByteBuffer.allocateDirect( bufferSize );
    newBuffer.put( buffer );
    newBuffer.rewind();
    buffer = newBuffer;
    intBufferView = buffer.asIntBuffer();
}

但是,通過這種優化,區域增長算法大約需要33秒才能完成同一張圖像。 這是我無法解釋的性能下降。 是我的實現,整個想法還是這里的問題?

坦白說,我認為整個想法都是錯誤的。 Buffer類針對與您不同的用例進行了優化。 即在I / O設備之間來回傳輸數據(廣義上。

如果要獲得比當前更好的性能,請將Buffer替換為int[] 我預計您會看到較小的性能下降(與ArrayList<Point>版本相比),但是仍然會看到下降。 那就是您為節省內存而付出的代價。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM