简体   繁体   English

android方法调用性能

[英]android method call performance

EDIT: so, this happens only on android, on desktop results are pretty much the same, but on android ugly code is 10x faster. 编辑:所以,这仅发生在android上,在桌面上的结果几乎相同,但是在android上,丑陋的代码要快10倍。 Tested on android 4.4 (samsung galaxy s4), android 8 (nexus 6p), android emulator on Mac. 在android 4.4(三星银河s4),android 8(nexus 6p)和android模拟器上进行了测试。

After refactoring code of my android program I noticed, that method invocation is very performance costly. 在重构我的android程序的代码后,我注意到,该方法调用的性能非常昂贵。 Lets say, I have a class 可以说,我有一堂课

public class Chunk {
private byte[] chunkArray;
private ChunkGetter chunkGetter;

public Chunk() {
    chunkArray = new byte[65536];
    chunkGetter = new ChunkGetter();
}

public byte getByteFromArray(int x, int y, int z) {
    return chunkGetter.getBlockId(x, y, z, chunkArray);
}

public byte[] getChunkArray() {
    return chunkArray;
    }
}

and a getter to get data from a chunk array: 以及从块数组中获取数据的吸气剂:

public ChunkGetter() {

}

public byte getBlockId(int x, int y, int z, byte[] blocksByteArray) {
    return blocksByteArray[getCoordinateOffset(x, y, z)];
}

public static int getCoordinateOffset(int x, int y, int z) {
    return x * 256 * 16 + z * 256 + y;
}

So, a simple getting test gave me these results: 因此,一个简单的测试给了我这些结果:

private void runTest() {
    Chunk chunk = new Chunk();
    long start = System.nanoTime();
    for (int x = 0; x < 16; x++) {
        for (int z = 0; z < 16; z++) {
            for (int y = 0; y < 256; y++) {
                byte id = chunk.getByteFromArray(x, y, z);
            }
        }
    }
    LOG("test took: " + (System.nanoTime() - start) / 1000000 + " ms");
}
first call: test took: 19 ms
second call: test took: 16 ms
third call: test took: 17 ms

But if I get data directly from the array - it is 20 times faster: 但是,如果我直接从数组中获取数据-速度会提高20倍:

private void runTest() {
    Chunk chunk = new Chunk();
    byte[] chunkArray = chunk.getChunkArray();
    long start = System.nanoTime();
    for (int x = 0; x < 16; x++) {
        for (int z = 0; z < 16; z++) {
            for (int y = 0; y < 256; y++) {
                byte id = chunkArray[x * 256 * 16 + z * 256 + y];
            }
        }
    }
    LOG("test took: " + (System.nanoTime() - start) / 1000000 + " ms");
}
first call: test took: 1 ms
second call: test took: 1 ms
third call: test took: 1 ms

This code is not readable and not flexible but when using it, my program runs init method in 1.5 sec and when using methods - it runs in 9 sec! 该代码不可读也不灵活,但是在使用时,我的程序在1.5秒内运行init方法,而在使用方法时-在9秒内运行! How can I achieve good performance without ugly copy-pasting? 如何在不进行复制粘贴的情况下获得良好的性能?

The Android virtual machine seems to lack some of the optimizations of the desktop JRE's HotSpot engine, maybe the auto-inlining of calls. Android虚拟机似乎缺乏桌面JRE的HotSpot引擎的某些优化,也许是呼叫的自动内联。 If that's true, you have to reduce the number of method calls. 如果是这样,则必须减少方法调用的次数。

Some ideas: 一些想法:

  • Inline the getCoordinateOffset() and getBlockId() methods into Chunk.getByteFromArray() - from your code snippet, I don't see a reason for having a ChunkGetter class. getCoordinateOffset()getBlockId()方法内联到Chunk.getByteFromArray() -从您的代码片段中,我看不到拥有ChunkGetter类的原因。 In the outer layer, you'll still have the x/y/z abstraction, and it gets "ugly" only inside the implementing code of getByteFromArray() 在外层,您仍然具有x / y / z抽象,并且仅在getByteFromArray()的实现代码内会变得“丑陋”

  • Why do you represent a logically 3-dimensional array as a linear array, thus making the strange index computation necessary? 为什么将逻辑3维数组表示为线性数组,从而使奇怪的索引计算成为必要? Directly using a three-dimensional array eliminates the need for the special getters, and might be quite fast. 直接使用三维数组消除了对特殊吸气剂的需求,而且速度可能很快。

  • Your nested loops effectively traverse your linearized array sequentially. 嵌套循环可有效地顺序遍历线性化数组。 Instead, you could do a single loop for (int i=0; i<chunkArray.length; i++) . 相反,您可以for (int i=0; i<chunkArray.length; i++)做一个循环。 No x/y/z abstraction, but probably even faster than your faster version. 没有x / y / z抽象,但可能比更快的版本还要快。

Maybe some of these hints might help - only benchmarking will tell, and you decide on the tradeoff between (your view of) readability and speed. 也许其中一些提示可能会有所帮助-只有基准测试才能说明问题,您可以在(您的观点)可读性和速度之间做出权衡。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM