массивная память используется в нескольких внутренних циклах - PullRequest
0 голосов
/ 13 февраля 2011

Я написал статический метод, который использует 4 внутренних цикла, как показано ниже. Я много и много тестировал кучу, используемую при ее запуске. Кажется, что он генерирует тысячи и тысячи объектов типа «int []», я думаю, что они происходят из циклов, которые я создал.

Я не могу найти способ обойти эту проблему с памятью, мне нужны циклы, но мне не нужно много объектов int [], созданных для каждого цикла, это просто пустая трата! Это сами петли, которые вызывают эти ошибки? И есть ли что-нибудь, что я могу сделать, чтобы уменьшить использование памяти, я думал о расширенном цикле, но это может быть той же проблемой ...

Спасибо!

    public static double[] calculateHand(final int card1, final int card2, final int card3,
        final int card4, final int card5)
{
    int ahead = 0, tied = 1, behind = 2;
    int[][] HP = new int[3][3];
    int[] HPTotal = new int[3];

    int ourrank = HandEval.hand5Eval(HandEval.encode(card1, card2, card3, card4, card5));

    int[] remainingCards = filterCardsFromDeck(card1, card2, card3, card4, card5);

    int kM = 1

    for (int i = 0; i < remainingCards.length; i++)
    {

        for (int k = kM; k < remainingCards.length; k++)
        {
            int index = -1;
            int oCard1 = remainingCards[i];
            int oCard2 = remainingCards[k];

            int opprank = HandEval.hand5Eval(HandEval
                    .encode(oCard1, oCard2, card3, card4, card5));

            if (ourrank > opprank)
            {
                index = ahead;
            }
            else if (ourrank == opprank)
            {
                index = tied;
            }

            else
            {
                index = behind;
            }

            HPTotal[index]++;
            int[] newArray = filter2Cards(remainingCards, oCard1, oCard2);

            int riverMinimumIndex = 1;
            for (int turnIndex = 0; turnIndex < newArray.length; turnIndex++)
            {

                for (int riverIndex = riverMinimumIndex; riverIndex < newArray.length; riverIndex++)
                {

                    int turnCard = newArray[turnIndex];
                    int riverCard = newArray[riverIndex];
                    int ourbest = HandEval.hand7Eval(HandEval.encode7(card1, card2, card3, card4,
                            card5, turnCard, riverCard));

                    int oppbest = HandEval.hand7Eval(HandEval.encode7(oCard1, oCard2, card3, card4,
                            card5, turnCard, riverCard));

                    if (ourbest > oppbest)
                    {
                        HP[index][ahead]++;
                    }

                    else if (ourbest == oppbest)
                    {
                        HP[index][tied]++;
                    }

                    else
                    {
                        HP[index][behind]++;
                    }
                }
                riverMinimumIndex++;
            }
        }
        kM++;
    }

    .....

    return result;
}

Ответы [ 2 ]

2 голосов
/ 13 февраля 2011

В этом методе есть четыре места, где массивы создаются (или, вероятно, создаются):

int[][] HP = new int[3][3];
int[] HPTotal = new int[3];
...
int[] remainingCards = filterCardsFromDeck(card1, card2, card3, card4, card5);
...
int[] newArray = filter2Cards(remainingCards, oCard1, oCard2);

(Возможно также, что некоторые другие методы, которые вы вызываете, создают ... и отбрасывают ... временные массивы. Их должно быть легко обнаружить.)

Первые три происходят один раз за вызов вашего метода и, вероятно, не являются существенной проблемой. Последний происходит в цикле 2-го уровня и (если мое чтение верно) будет выполнен O(N**2) раз, где N - количество карточек.

Что с этим делать? (Очевидный ответ - просто оставить это в покое, если у вас нет четких доказательств того, что это влияет на производительность приложения. Но я предполагаю, что вы уже прошли это.)

Лучшее, что я могу придумать, - это рефакторинг вашего кода, чтобы filter2Cards принял существующий массив в качестве аргумента и заполнил его отфильтрованными карточками. Он должен будет возвращать int с указанием количества значений, добавленных в массив, и следующий код должен будет использовать это значение вместо длины массива. Затем переместите создание массива до самого внешнего цикла.

Очевидно, это делает ваш код более сложным. Это штраф, который вы платите ...

0 голосов
/ 13 февраля 2011

Я предполагаю, что кучи инфляции, о которой вы говорили, были бы восприняты как часть развития виртуальной машины.Это не невозможно , что вы видите проблему с виртуальной машиной, но без публикации остального кода, я думаю, что проблема заключается не только в циклах, а скорее в том, что вы ввели в свойдругой код.Если вы опубликуете это, возможно, мы сможем вам помочь.

...