Java Android设备上的for循环速度非常慢
我在为android设备编写位图操作算法时遇到了一个问题 我有一个1680x128像素的位图,需要应用一个过滤器。但这段非常简单的代码实际上在我的Android设备(带有1Ghz处理器的xperia ray)上运行了将近15-20秒 因此,我试图找到瓶颈,并尽可能减少代码行,最终得到循环本身,这几乎花费了相同的时间来运行Java Android设备上的for循环速度非常慢,java,android,performance,for-loop,heap,Java,Android,Performance,For Loop,Heap,我在为android设备编写位图操作算法时遇到了一个问题 我有一个1680x128像素的位图,需要应用一个过滤器。但这段非常简单的代码实际上在我的Android设备(带有1Ghz处理器的xperia ray)上运行了将近15-20秒 因此,我试图找到瓶颈,并尽可能减少代码行,最终得到循环本身,这几乎花费了相同的时间来运行 for (int j = 0; j < 128; j++) { for (int i = 0; i < 1680; i++) { Doub
for (int j = 0; j < 128; j++) {
for (int i = 0; i < 1680; i++) {
Double test = Math.random();
}
}
for(int j=0;j<128;j++){
对于(int i=0;i<1680;i++){
双重测试=数学随机();
}
}
这种设备在一个简单的for循环中花费如此多的时间而没有困难的操作,这正常吗
我对在移动设备上编程非常陌生,所以如果这个问题可能很愚蠢,请原谅
更新:通过一些简单的操作,现在速度更快了
但回到我的主要问题:
public static void filterImage(Bitmap img, FilterStrategy filter) {
img.prepareToDraw();
int height = img.getHeight();
int width = img.getWidth();
RGB rgb;
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
rgb = new RGB(img.getPixel(i, j));
if (filter.isBlack(rgb)) {
img.setPixel(i, j, 0);
} else
img.setPixel(i, j, 0xffffffff);
}
}
return;
}
公共静态无效过滤器图像(位图img、过滤器策略过滤器){
img.prepareToDraw();
int height=img.getHeight();
int width=img.getWidth();
RGB-RGB;
对于(int j=0;j
上面的代码是我真正需要在设备上运行得更快的代码。(几乎立即)
你认为它有优化的潜力吗
RGB只是一个计算红色、绿色和蓝色值的类,如果所有三个颜色部分都低于100或任何其他指定值,则过滤器仅返回true。
围绕img.getPixel(i,j)或setPixel的循环需要20秒或更长时间。这是一个如此昂贵的操作吗?可能是因为创建了太多的Double类型的对象。。因此,它增加了堆大小,设备开始冻结 一种方法是
double[] arr = new double[128]
for (int j = 0; j < 128; j++) {
for (int i = 0; i < 1680; i++) {
arr[i] = Math.random();
}
}
double[]arr=新的双精度[128]
对于(int j=0;j<128;j++){
对于(int i=0;i<1680;i++){
arr[i]=Math.random();
}
}
下面的文档中有一个免责声明,对于可能影响性能的随机事件,请尝试自己创建一个实例,而不是使用静态版本,我已经用粗体突出显示了性能免责声明:
返回伪随机双精度n,其中n>=0.0&&n<1.0。此方法重用单个Random实例。这种方法是线程安全的,因为对随机数据的访问是同步的,但这会损害可伸缩性应用程序可以从为每个线程分配一个随机线程中获得性能优势。
尝试创建自己的random作为类的静态字段,以避免同步访问:
private static Random random = new Random();
然后按如下方式使用:
double r = random.nextDouble();
如果不需要双精度,请考虑使用浮点(No.NeXFLUATE())。< /P> RGB只是一个计算红色、绿色和蓝色值的类,如果所有三个颜色部分都低于100或任何其他指定值,则过滤器仅返回true
一个问题是,您正在创建RGB类的height*width
实例,只是为了测试单个pizel是否为黑色。将该方法替换为静态方法调用,该调用将要测试的像素作为参数
更一般地说,如果您不知道为什么某些代码很慢对其进行分析。在这种情况下,探查器会告诉您RGB构造函数花费了大量时间。内存分析器会告诉你大量的RGB对象正在被创建和垃圾收集。首先Stephen C提出了一个很好的论点:尽量避免创建一堆RGB对象 其次,您可以通过将对
getPixel
的相对昂贵的调用替换为对
我做了一些快速测试,并设法将运行时间缩短到10%左右。试试看。这就是我使用的代码:
int[] pixels = new int[height * width];
img.getPixels(pixels, 0, width, 0, 0, width, height);
for(int pixel:pixels) {
// check the pixel
}
双重测试;for(intj=0;j<500;j++)for(inti=0;i<100;i++)test=Math.random()//这不是更快…好吧,我现在更快了(<1秒)。。。你知道如何加速上面添加的代码吗?很好,但即使我注释掉所有这些行并简单地迭代所有像素以将它们设置为黑色,代码也会持续20秒。怎么会呢?我现在正在做。setPixel每次运行checkPixelAccess(45%)和其他方法。nativeSetPixel调用本身只有每个setPixel调用7%的cpu时间。我现在就用@sandis代码块试试。希望这有助于避免这些毫无意义的调用。这和其他一些更改加快了算法的速度。感谢您的快速建议:)