简体   繁体   English

对象的初始化要比对象的构造函数花更长的时间:Java

[英]Initialization of object is taking longer than constructor of the object: Java

So I am utilizing an algorithm for an application that I am making on the Android phone. 因此,我正在为我在Android手机上制作的应用程序使用一种算法。 Supposedly, the algorithm should only take milliseconds to execute on a computer. 据推测,该算法只需几毫秒即可在计算机上执行。 However it is taking less than 2 seconds, which is going to be significant, especially since the android processor is a lot slower than the one on my computer. 然而,这只需要不到2秒的时间,这将非常重要,特别是因为android处理器比我的计算机上的处理器慢很多。

I tried to pinpoint what exactly was causing this huge amount of time, and it ended up being one line of code. 我试图查明究竟是什么导致了这么长的时间,最终导致了一行代码。 Apparantly: Apparantly:

Object A = new ObjectA();

takes about 95% of the entire execution time. 大约占整个执行时间的95%。 I checked how long the constructor for ObjectA takes, and it takes almost 0 seconds. 我检查了ObjectA的构造函数花费了多长时间,并且花费了将近0秒。 Why does the program spend most of its time here? 为什么该程序将大部分时间都花在这里? Is it because it takes time to allocate that much space into memory? 是因为将这么多空间分配到内存需要时间吗? Or is there some other underlying reason due to the way java works? 还是由于Java的工作方式而存在其他一些潜在的原因? And is there anyway to optimize it to prevent from taking so much time? 是否有任何方法对其进行优化以防止花费大量时间?

Edited to include actual class This is the CoordCube Class from Kociemba's algorithm which is initialized inside of Search.java Essentially, the constructor takes 0 seconds, whereas the declaration 编辑为包括实际类这是Kociemba算法中的CoordCube类,该类在Search.java内部进行了初始化。本质上,构造函数花费0秒,而声明

CoordCube cube = new CoordCube(cc);//where cc is cubiecube

takes a long time 需要很长的时间

package org.kociemba.twophase;

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Representation of the cube on the coordinate level class CoordCube { // ++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++ //坐标级类CoordCube {

static final short N_TWIST = 2187;// 3^7 possible corner orientations
static final short N_FLIP = 2048;// 2^11 possible edge flips
static final short N_SLICE1 = 495;// 12 choose 4 possible positions of FR,FL,BL,BR edges
static final short N_SLICE2 = 24;// 4! permutations of FR,FL,BL,BR edges in phase2
static final short N_PARITY = 2; // 2 possible corner parities
static final short N_URFtoDLF = 20160;// 8!/(8-6)! permutation of URF,UFL,ULB,UBR,DFR,DLF corners
static final short N_FRtoBR = 11880; // 12!/(12-4)! permutation of FR,FL,BL,BR edges
static final short N_URtoUL = 1320; // 12!/(12-3)! permutation of UR,UF,UL edges
static final short N_UBtoDF = 1320; // 12!/(12-3)! permutation of UB,DR,DF edges
static final short N_URtoDF = 20160; // 8!/(8-6)! permutation of UR,UF,UL,UB,DR,DF edges in phase2

static final int N_URFtoDLB = 40320;// 8! permutations of the corners
static final int N_URtoBR = 479001600;// 8! permutations of the corners

static final short N_MOVE = 18;

// All coordinates are 0 for a solved cube except for UBtoDF, which is 114
short twist;
short flip;
short parity;
short FRtoBR;
short URFtoDLF;
short URtoUL;
short UBtoDF;
int URtoDF;

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Generate a CoordCube from a CubieCube
CoordCube(CubieCube c) {
    twist = c.getTwist();
    flip = c.getFlip();
    parity = c.cornerParity();
    FRtoBR = c.getFRtoBR();
    URFtoDLF = c.getURFtoDLF();
    URtoUL = c.getURtoUL();
    UBtoDF = c.getUBtoDF();
    URtoDF = c.getURtoDF();// only needed in phase2

}

// A move on the coordinate level
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void move(int m) {
    twist = twistMove[twist][m];
    flip = flipMove[flip][m];
    parity = parityMove[parity][m];
    FRtoBR = FRtoBR_Move[FRtoBR][m];
    URFtoDLF = URFtoDLF_Move[URFtoDLF][m];
    URtoUL = URtoUL_Move[URtoUL][m];
    UBtoDF = UBtoDF_Move[UBtoDF][m];
    if (URtoUL < 336 && UBtoDF < 336)// updated only if UR,UF,UL,UB,DR,DF
        // are not in UD-slice
        URtoDF = MergeURtoULandUBtoDF[URtoUL][UBtoDF];
}

// ******************************************Phase 1 move tables*****************************************************

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Move table for the twists of the corners
// twist < 2187 in phase 2.
// twist = 0 in phase 2.
static short[][] twistMove = new short[N_TWIST][N_MOVE];
static {
    CubieCube a = new CubieCube();
    for (short i = 0; i < N_TWIST; i++) {
        a.setTwist(i);
        for (int j = 0; j < 6; j++) {
            for (int k = 0; k < 3; k++) {
                a.cornerMultiply(CubieCube.moveCube[j]);
                twistMove[i][3 * j + k] = a.getTwist();
            }
            a.cornerMultiply(CubieCube.moveCube[j]);// 4. faceturn restores
            // a
        }
    }
}

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Move table for the flips of the edges
// flip < 2048 in phase 1
// flip = 0 in phase 2.
static short[][] flipMove = new short[N_FLIP][N_MOVE];
static {
    CubieCube a = new CubieCube();
    for (short i = 0; i < N_FLIP; i++) {
        a.setFlip(i);
        for (int j = 0; j < 6; j++) {
            for (int k = 0; k < 3; k++) {
                a.edgeMultiply(CubieCube.moveCube[j]);
                flipMove[i][3 * j + k] = a.getFlip();
            }
            a.edgeMultiply(CubieCube.moveCube[j]);
            // a
        }
    }
}

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Parity of the corner permutation. This is the same as the parity for the edge permutation of a valid cube.
// parity has values 0 and 1
static short[][] parityMove = { { 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1 },
        { 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0 } };

// ***********************************Phase 1 and 2 movetable********************************************************

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Move table for the four UD-slice edges FR, FL, Bl and BR
// FRtoBRMove < 11880 in phase 1
// FRtoBRMove < 24 in phase 2
// FRtoBRMove = 0 for solved cube
static short[][] FRtoBR_Move = new short[N_FRtoBR][N_MOVE];
static {
    CubieCube a = new CubieCube();
    for (short i = 0; i < N_FRtoBR; i++) {
        a.setFRtoBR(i);
        for (int j = 0; j < 6; j++) {
            for (int k = 0; k < 3; k++) {
                a.edgeMultiply(CubieCube.moveCube[j]);
                FRtoBR_Move[i][3 * j + k] = a.getFRtoBR();
            }
            a.edgeMultiply(CubieCube.moveCube[j]);
        }
    }
}

// *******************************************Phase 1 and 2 movetable************************************************

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Move table for permutation of six corners. The positions of the DBL and DRB corners are determined by the parity.
// URFtoDLF < 20160 in phase 1
// URFtoDLF < 20160 in phase 2
// URFtoDLF = 0 for solved cube.
static short[][] URFtoDLF_Move = new short[N_URFtoDLF][N_MOVE];
static {
    CubieCube a = new CubieCube();
    for (short i = 0; i < N_URFtoDLF; i++) {
        a.setURFtoDLF(i);
        for (int j = 0; j < 6; j++) {
            for (int k = 0; k < 3; k++) {
                a.cornerMultiply(CubieCube.moveCube[j]);
                URFtoDLF_Move[i][3 * j + k] = a.getURFtoDLF();
            }
            a.cornerMultiply(CubieCube.moveCube[j]);
        }
    }
}

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Move table for the permutation of six U-face and D-face edges in phase2. The positions of the DL and DB edges are
// determined by the parity.
// URtoDF < 665280 in phase 1
// URtoDF < 20160 in phase 2
// URtoDF = 0 for solved cube.
static short[][] URtoDF_Move = new short[N_URtoDF][N_MOVE];
static {
    CubieCube a = new CubieCube();
    for (short i = 0; i < N_URtoDF; i++) {
        a.setURtoDF(i);
        for (int j = 0; j < 6; j++) {
            for (int k = 0; k < 3; k++) {
                a.edgeMultiply(CubieCube.moveCube[j]);
                URtoDF_Move[i][3 * j + k] = (short) a.getURtoDF();
                // Table values are only valid for phase 2 moves!
                // For phase 1 moves, casting to short is not possible.
            }
            a.edgeMultiply(CubieCube.moveCube[j]);
        }
    }
}

// **************************helper move tables to compute URtoDF for the beginning of phase2************************

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Move table for the three edges UR,UF and UL in phase1.
static short[][] URtoUL_Move = new short[N_URtoUL][N_MOVE];
static {
    CubieCube a = new CubieCube();
    for (short i = 0; i < N_URtoUL; i++) {
        a.setURtoUL(i);
        for (int j = 0; j < 6; j++) {
            for (int k = 0; k < 3; k++) {
                a.edgeMultiply(CubieCube.moveCube[j]);
                URtoUL_Move[i][3 * j + k] = a.getURtoUL();
            }
            a.edgeMultiply(CubieCube.moveCube[j]);
        }
    }
}

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Move table for the three edges UB,DR and DF in phase1.
static short[][] UBtoDF_Move = new short[N_UBtoDF][N_MOVE];
static {
    CubieCube a = new CubieCube();
    for (short i = 0; i < N_UBtoDF; i++) {
        a.setUBtoDF(i);
        for (int j = 0; j < 6; j++) {
            for (int k = 0; k < 3; k++) {
                a.edgeMultiply(CubieCube.moveCube[j]);
                UBtoDF_Move[i][3 * j + k] = a.getUBtoDF();
            }
            a.edgeMultiply(CubieCube.moveCube[j]);
        }
    }
}

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Table to merge the coordinates of the UR,UF,UL and UB,DR,DF edges at the beginning of phase2
static short[][] MergeURtoULandUBtoDF = new short[336][336];
static {
    // for i, j <336 the six edges UR,UF,UL,UB,DR,DF are not in the
    // UD-slice and the index is <20160
    for (short uRtoUL = 0; uRtoUL < 336; uRtoUL++) {
        for (short uBtoDF = 0; uBtoDF < 336; uBtoDF++) {
            MergeURtoULandUBtoDF[uRtoUL][uBtoDF] = (short) CubieCube.getURtoDF(uRtoUL, uBtoDF);
        }
    }
}

// ****************************************Pruning tables for the search*********************************************

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Pruning table for the permutation of the corners and the UD-slice edges in phase2.
// The pruning table entries give a lower estimation for the number of moves to reach the solved cube.
static byte[] Slice_URFtoDLF_Parity_Prun = new byte[N_SLICE2 * N_URFtoDLF * N_PARITY / 2];
static {
    for (int i = 0; i < N_SLICE2 * N_URFtoDLF * N_PARITY / 2; i++)
        Slice_URFtoDLF_Parity_Prun[i] = -1;
    int depth = 0;
    setPruning(Slice_URFtoDLF_Parity_Prun, 0, (byte) 0);
    int done = 1;
    while (done != N_SLICE2 * N_URFtoDLF * N_PARITY) {
        for (int i = 0; i < N_SLICE2 * N_URFtoDLF * N_PARITY; i++) {
            int parity = i % 2;
            int URFtoDLF = (i / 2) / N_SLICE2;
            int slice = (i / 2) % N_SLICE2;
            if (getPruning(Slice_URFtoDLF_Parity_Prun, i) == depth) {
                for (int j = 0; j < 18; j++) {
                    switch (j) {
                    case 3:
                    case 5:
                    case 6:
                    case 8:
                    case 12:
                    case 14:
                    case 15:
                    case 17:
                        continue;
                    default:
                        int newSlice = FRtoBR_Move[slice][j];
                        int newURFtoDLF = URFtoDLF_Move[URFtoDLF][j];
                        int newParity = parityMove[parity][j];
                        if (getPruning(Slice_URFtoDLF_Parity_Prun, (N_SLICE2 * newURFtoDLF + newSlice) * 2 + newParity) == 0x0f) {
                            setPruning(Slice_URFtoDLF_Parity_Prun, (N_SLICE2 * newURFtoDLF + newSlice) * 2 + newParity,
                                    (byte) (depth + 1));
                            done++;
                        }
                    }
                }
            }
        }
        depth++;
    }
}

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Pruning table for the permutation of the edges in phase2.
// The pruning table entries give a lower estimation for the number of moves to reach the solved cube.
static byte[] Slice_URtoDF_Parity_Prun = new byte[N_SLICE2 * N_URtoDF * N_PARITY / 2];
static {
    for (int i = 0; i < N_SLICE2 * N_URtoDF * N_PARITY / 2; i++)
        Slice_URtoDF_Parity_Prun[i] = -1;
    int depth = 0;
    setPruning(Slice_URtoDF_Parity_Prun, 0, (byte) 0);
    int done = 1;
    while (done != N_SLICE2 * N_URtoDF * N_PARITY) {
        for (int i = 0; i < N_SLICE2 * N_URtoDF * N_PARITY; i++) {
            int parity = i % 2;
            int URtoDF = (i / 2) / N_SLICE2;
            int slice = (i / 2) % N_SLICE2;
            if (getPruning(Slice_URtoDF_Parity_Prun, i) == depth) {
                for (int j = 0; j < 18; j++) {
                    switch (j) {
                    case 3:
                    case 5:
                    case 6:
                    case 8:
                    case 12:
                    case 14:
                    case 15:
                    case 17:
                        continue;
                    default:
                        int newSlice = FRtoBR_Move[slice][j];
                        int newURtoDF = URtoDF_Move[URtoDF][j];
                        int newParity = parityMove[parity][j];
                        if (getPruning(Slice_URtoDF_Parity_Prun, (N_SLICE2 * newURtoDF + newSlice) * 2 + newParity) == 0x0f) {
                            setPruning(Slice_URtoDF_Parity_Prun, (N_SLICE2 * newURtoDF + newSlice) * 2 + newParity,
                                    (byte) (depth + 1));
                            done++;
                        }
                    }
                }
            }
        }
        depth++;
    }
}

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Pruning table for the twist of the corners and the position (not permutation) of the UD-slice edges in phase1
// The pruning table entries give a lower estimation for the number of moves to reach the H-subgroup.
static byte[] Slice_Twist_Prun = new byte[N_SLICE1 * N_TWIST / 2 + 1];
static {
    for (int i = 0; i < N_SLICE1 * N_TWIST / 2 + 1; i++)
        Slice_Twist_Prun[i] = -1;
    int depth = 0;
    setPruning(Slice_Twist_Prun, 0, (byte) 0);
    int done = 1;
    while (done != N_SLICE1 * N_TWIST) {
        for (int i = 0; i < N_SLICE1 * N_TWIST; i++) {
            int twist = i / N_SLICE1, slice = i % N_SLICE1;
            if (getPruning(Slice_Twist_Prun, i) == depth) {
                for (int j = 0; j < 18; j++) {
                    int newSlice = FRtoBR_Move[slice * 24][j] / 24;
                    int newTwist = twistMove[twist][j];
                    if (getPruning(Slice_Twist_Prun, N_SLICE1 * newTwist + newSlice) == 0x0f) {
                        setPruning(Slice_Twist_Prun, N_SLICE1 * newTwist + newSlice, (byte) (depth + 1));
                        done++;
                    }
                }
            }
        }
        depth++;
    }
}

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Pruning table for the flip of the edges and the position (not permutation) of the UD-slice edges in phase1
// The pruning table entries give a lower estimation for the number of moves to reach the H-subgroup.
static byte[] Slice_Flip_Prun = new byte[N_SLICE1 * N_FLIP / 2];
static {
    for (int i = 0; i < N_SLICE1 * N_FLIP / 2; i++)
        Slice_Flip_Prun[i] = -1;
    int depth = 0;
    setPruning(Slice_Flip_Prun, 0, (byte) 0);
    int done = 1;
    while (done != N_SLICE1 * N_FLIP) {
        for (int i = 0; i < N_SLICE1 * N_FLIP; i++) {
            int flip = i / N_SLICE1, slice = i % N_SLICE1;
            if (getPruning(Slice_Flip_Prun, i) == depth) {
                for (int j = 0; j < 18; j++) {
                    int newSlice = FRtoBR_Move[slice * 24][j] / 24;
                    int newFlip = flipMove[flip][j];
                    if (getPruning(Slice_Flip_Prun, N_SLICE1 * newFlip + newSlice) == 0x0f) {
                        setPruning(Slice_Flip_Prun, N_SLICE1 * newFlip + newSlice, (byte) (depth + 1));
                        done++;
                    }
                }
            }
        }
        depth++;
    }
}

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Set pruning value in table. Two values are stored in one byte.
static void setPruning(byte[] table, int index, byte value) {
    if ((index & 1) == 0)
        table[index / 2] &= 0xf0 | value;
    else
        table[index / 2] &= 0x0f | (value << 4);
}

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Extract pruning value
static byte getPruning(byte[] table, int index) {
    if ((index & 1) == 0)
        return (byte) (table[index / 2] & 0x0f);
    else
        return (byte) ((table[index / 2] & 0xf0) >>> 4);
}

} }

You have lots of static blocks in your code, read more about static blocks here . 您的代码中有很多static块,请在此处阅读有关static块的更多信息。 Static blocks are executed when the class is loaded, the class can have any number of static blocks and all are called in the order they appear in the code. 静态块是在加载类时执行的,该类可以具有任意数量的static块,并且全部按照它们在代码中出现的顺序进行调用。

From link: 来自链接:

A static initializer declared in a class is executed when the class is initialized (§12.4.2). Together with any field initializers for class variables (§8.3.2), static initializers may be used to initialize the class variables of the class.

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

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