Проблемы с производительностью с течением времени - PullRequest
1 голос
/ 22 мая 2011

Эй, я делаю простую текстовую игру, используя библиотеку pdCurses и некоторые другие мелочи, вроде вертикального скроллера, в котором вы избегаете случайно сгенерированных стен .... Есть две стены слева и справа, сделанные из символов «X», и пустое черное пространство, в котором вы можете перемещаться и избегать «X», ваш персонаж - «8», и вы вынуждены двигаться вперед или касаться друг друга X время, когда обнаруживается новая строка случайно сгенерированной «карты» (для тестов производительности я сделал новую строку, показанную как можно быстрее).

Однако у меня есть некоторые проблемы с производительностью, так как «карта» (вектор строк) становится все больше и больше. Я не понимаю проблемы, однако, поскольку я не использую все это в любое время, я только вытаскиваю ее части для отображения (обычно 56 строк).

Я покажу вам, что у меня есть, и, надеюсь, кто-то поможет или предложит лучший способ добиться успеха в моей игре.

Вот сокращенный, важный код: Вот функция, которая занимает примерно 0,25,75 секунды (new_map также является векторным членом класса "Screen"):

    void Insert(const Map& map, int y1, int y2) {for ( int mc = y1, nm= 0; mc< map.Contents().size() && mc< y2; mc++, nm++)
                                                 new_map[nm] = map.Contents(mc);};

Вот функции содержания классов Map:

string Contents(int Y)      {return contents[Y];};
char Contents(int Y, int X) {return contents[Y][X];};
vector <string> Save()      {return save;};

и, наконец, main () , который я установил, чтобы экран обновлялся как можно быстрее ... что не так быстро, о, и L1 - одна из моих "карт" ... генерировать добавляет новые строки на карту, так что это никогда не заканчивается:

 double refreshes= 0;
for (bool quit = false; quit != true;)
{   double newTime= myStopwatch.ElapsedTime()- refreshes;
    theScreen.Insert(L1, 0+refreshes, nrows+refreshes);
    refreshes++;
    if(L1.Contents().size()<= nrows+refreshes+2)
        L1.generate();}

Спасибо за любую помощь или советы! Я знаю, это довольно ужасно, но я только начал программировать 2 месяца назад, ха-ха! =) спросите, нужна ли вам дополнительная информация.

Ответы [ 2 ]

2 голосов
/ 22 мая 2011

Похоже, что общая проблема заключается в том, что по мере того, как ваш набор данных получает большие объемы, например копирует его (что вы, кажется, делаете постоянно, например, в своем фрагменте вы копируете строки из одного вектора в другой), это занимает больше времени.

Что нужно учитывать:

  1. Вам нужны данные, которые поступают с экрана?
  2. Можете ли вы использовать массив в стиле C? Как правило, это будет быстрее, и вы также сможете более четко увидеть, в чем заключается неэффективность.
  3. Попробуйте думать о своей прокрутке как о просто перемещении точки, из которой вы получаете данные, на экран. Вам не нужно делать копии или перемещать данные.

В качестве примера для пункта # 1 вы можете предпочесть сохранить строки экрана в списке и сделать что-то вроде:

std::list<string> screen;
// fill up with your initial screen.
generate(line); // generate your new line
screen.push_back(line); // to add a line
screen.pop_front(); // remove a line from the top

Это не идеально (есть управление памятью и некоторое копирование за кулисами), но оно превзойдет копирование и накопление всех строк экрана.

В качестве примера для пункта № 2 рассмотрим следующий код:

char screen[25][80];
for(int y = 0; y < 25; y++)
{
  for(int x = 0; x < 79; x++)
  {
    screen[y][x] = screen[y][x+1];
  }
}

Это «прокрутит» экран на один символ влево. Он будет работать постоянно и довольно быстро - на любом современном процессоре вы можете рассчитывать на выполнение более миллиона операций прокрутки в секунду.

0 голосов
/ 22 мая 2011

Вместо этого попробуйте unordered_map, его рабочие характеристики несколько лучше с ростом размера. упс, у вас есть собственный класс Map, который не имеет ничего общего с std::map.

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

Вы можете подумать о том, чтобы как-то отслеживать индексы, вместо того, чтобы копировать сами строки.

...