Контекст
Я использую QLinkedList для хранения некоторого класса, который я написал.
Дело в том, что я должен перебрать много по этому списку.
Я имею в виду, что программа, которую я пишу, создает бесконечное исчисление (ну, вы все равно можете остановить его вручную), и мне нужно пройти через это QLinkedList для каждой итерации.
Задача
Проблема не в том, много ли я перебираю этот список.
Дело в том, что я профилирую свой код и вижу, что 1/4 времени уходит на функции QLinkedList :: end () и QLinkedList :: begin () .
Пример кода
Мой код следующий:
typedef QLinkedList<Particle*> ParticlesList; // Particle is a custom class
ParticlesList* parts = // assign a QLinkedList
for (ParticlesList::const_iterator itp = parts->begin(); itp != parts->end(); ++itp)
{
//make some calculus
}
Как я уже сказал, этот код вызывается так часто, что он тратит много времени на parts-> begin () и parts-> end () .
Вопрос
Итак, вопрос в том, как я могу сократить время, затрачиваемое на итерацию этого списка?
Возможные решения
Вот некоторые решения, о которых я подумал, пожалуйста, помогите мне выбрать лучшее или предложите мне другое:)
- Использование классического массива C: // извините за эту ошибку
Particle** parts = // assing it something
for (int n = 0; n < LENGTH; n++)
{
//access by index
//make some calculus
}
Это должно быть быстро, верно?
- Может быть, использовать итератор в стиле Java?
- Может быть, использовать другой контейнер?
- Асм? Шучу ... или может быть?
Спасибо за ваши будущие ответы!
PS: я прочитал сообщения от stackoverflow о том, когда нужно профилировать, так что не беспокойтесь об этом;)
Редактировать:
Список изменен
Извините, я думаю, что забыл самое важное, напишу всю функцию без зачистки:
typedef std::vector<Cell*> Neighbours;
typedef QLinkedList<Particle*> ParticlesList;
Neighbours neighbours = m_cell->getNeighbourhood();
Neighbours::const_iterator it;
for (it = neighbours.begin(); it != neighbours.end(); ++it)
{
ParticlesList* parts = (*it)->getParticles();
for (ParticlesList::const_iterator itp = parts->begin(); itp != parts->end(); ++itp)
{
double d = distanceTo(*itp); // computes sqrt(x^2 + y^2)
if(d>=0 && d<=m_maxForceRange)
{
particleIsClose(d, *itp); // just changes
}
}
}
И чтобы убедиться, что я полон, весь код вызывается в цикле ^^.
Так что да, список изменен и находится во внутреннем цикле. Таким образом, нет никакого способа предварительно вычислить начало и конец этого.
И, кроме того, список должен составляться на каждой большой итерации (я имею в виду в самом верхнем цикле), вставляя одну за другой.
Режим отладки
Да, действительно, я профилировал в режиме отладки. И я думаю, что это замечание было разумным, потому что в выпуске код работал в 2 раза быстрее. И проблема со списками исчезла.
Спасибо всем за ваши ответы и извините за это ^^