2014-06-05 59 views
-1

我试图优化我在Android设备上运行的简单区域增长算法。最初我使用ArrayList来保存属于一个地区的点。每个点都由一个Point实例描述,该实例需要为每个点实例化。它采用算法大约15秒找到约100万像素的图像内的所有区域。为什么Java本地缓冲区速度很慢?

class Point 
{ 
    public int x, y; 
} 

我以为我可以通过减少Point实例数量减少计算时间:为

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(); 
} 

对于添加点的区域I中使用这种方法:

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秒完成相同的图像。这是我无法解释的性能下降。这是我的执行,整个想法还是这里的问题?

+1

我之前和ByteBuffer一起工作过,它不需要任何接近毫秒的地方(甚至可能接近几秒钟,就像在你的手机上一样),但是你仍然会看到一个下降。案例)检查你自己的算法 - 99.99%的问题会出现在那里,99.99%的时间会出现在你做的一些代码中** not **在这里发帖 –

+0

我敢打赌你> 90所消耗时间的百分比(在显示的代码中)是s在成长中()。分配和复制数据是昂贵的部分。 – haraldK

+0

为什么选择投票? – theV0ID

回答

3

坦率地说,我认为这是整个想法是错误的。 Buffer类针对您的不同用户案例进行了优化;即传输数据到I/O设备(从广义上来说)

如果你想要更好(当前)性能,请用int[]代替Buffer。我预测你会看到一个较小的性能下降

+0

同意,更多的时候不是误导而是导致问题,而不是实际的系统和/或标准功能。 –

+0

谢谢你的澄清。还有一个问题。你预计性能下降与'int []'ArrayList '相比,对吧?我试过了,它给了我一个性能提升:现在,整个分段需要**约7-8秒**。我想知道是否可以通过JNI实现'Region'来实现更好的性能。 – theV0ID

+0

预测就像那样......而我是一个悲观主义者。 –

相关问题