Оптимизация C++ 2-D массивы

JFrame frame = new JFrame();

Прежде всего, это утверждение в вашем классе View совершенно не нужно. Вы не будете создавать экземпляр JFrame в конструкторе компонента. Также ваш код никогда не ссылается на переменную, что является хорошим признаком того, что она не нужна.

Однако основная проблема в том, что ваша концепция создания пользовательских компонентов неверна:

setPreferredSize(new Dimension(100, 100));

Вы пытаетесь установить предпочтительный размер компонента.

add(new Triangle(100, 200, Color.pink)); //this one doesn't appear

Но затем вы пытаетесь сделать свое собственное рисование в (100, 200), который находится за пределами размера компонента. Таким образом, логика рисования обрезается по размеру компонента, поэтому вы не видите ничего нарисованного.

Произвольная окраска должна выполняться относительно (0, 0) компонента, а не относительно родительского компонента.

Если вы хотите расположить компоненты случайным образом на родительской панели, вам необходимо:

  1. настроить родительскую панель на использование нулевого макета
  2. установить местоположение каждого компонента Вы добавляете на панель
  3. и задаете размер каждого компонента, который вы добавляете на панель.

В основном вам нужно взять на себя функции менеджера макета.

Другие проблемы с вашим текущим кодом рисования:

  1. Не вызывайте repaint () в методе рисования. Это по существу вызовет бесконечный цикл рисования. Если вам нужна анимация, вы используете Swing Timer для планирования анимации.

  2. Не вызывать paintComponent (...) напрямую. Swing вызовет paintComponent (), когда компонент должен быть перекрашен.

Однако я хотел бы предложить, чтобы, если вы хотите рисовать фигуры на панели, тогда вы забудете о создании пользовательских компонентов. Вместо этого вы сохраняете ArrayList тех фигур, которые хотите нарисовать, а затем в методе paintComponent () панели вы перебираете ArrayList для рисования каждой фигуры.

В качестве примера такого подхода рассмотрим пример Draw On Component, приведенный в Индивидуальные подходы к рисованию .

Примечание:

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

Проверьте Игра с формами для получения дополнительной информации об этой концепции.

7
задан Robert Gamble 12 November 2008 в 03:25
поделиться

10 ответов

При использовании GCC, компилятор может проанализировать матричные доступы и изменить порядок в памяти в определенных случаях. Волшебный флаг компилятора определяется как:

-fipa-matrix-reorg

Выполните матричное выравнивание и перемещение. Выравнивание матрицы пытается заменить m-dimensional матрицу своей эквивалентной n-мерной матрицей, где n <m. Это уменьшает уровень абстракции, необходимый для доступа к элементам матрицы. Вторая оптимизация является матрицей, транспонирующей это attemps для изменения порядка размеров матрицы для улучшения местности кэша. Для обеих оптимизации нужен флаг fwhole-программы. Перемещение включено, только если профильная информация доступна.

Обратите внимание, что эта опция не включена-O2 или-O3. Необходимо передать его сами.

8
ответ дан 6 December 2019 в 05:49
поделиться

Мое предположение было бы самым быстрым, для матрицы, чтобы использовать 1D массив STL и переопределить () оператор для использования его в качестве 2D матрицы.

Однако STL также определяет тип специально для числовых массивов неизменяемого размера: valarray. У Вас также есть различные оптимизации для оперативных операций.

valarray принимают как аргумент числовой тип:

valarray<double> a;

Затем можно использовать части, косвенные массивы... и конечно, можно наследовать valarray и определить собственный оператор () (интервал i, интервал j) для 2D массивов...

8
ответ дан 6 December 2019 в 05:49
поделиться

В Повышении существует uBLAS реализация. Это достойное внимания.

http://www.boost.org/doc/libs/1_36_0/libs/numeric/ublas/doc/matrix.htm

0
ответ дан 6 December 2019 в 05:49
поделиться

Вы могли столь же легко сделать вектор <двойной> (n*m);

1
ответ дан 6 December 2019 в 05:49
поделиться

Моя рекомендация состояла бы в том, чтобы использовать Повышение. UBLAS, который обеспечивает быстрые матричные/векторные классы.

6
ответ дан 6 December 2019 в 05:49
поделиться

Другая связанная библиотека является Блицем ++: http://www.oonumerics.org/blitz/docs/blitz.html

Блиц ++ разработан для оптимизации управления массивом.

0
ответ дан 6 December 2019 в 05:49
поделиться

Можно хотеть посмотреть на Собственную библиотеку шаблонов C++ по http://eigen.tuxfamily.org/. Это генерирует AltiVec или код sse2 для оптимизации векторных/матричных вычислений.

1
ответ дан 6 December 2019 в 05:49
поделиться

Быть справедливым зависит от алгоритмов, которые Вы используете на матрицу.

Двойное имя [n*m] формат очень быстро при доступе к данным строками и потому что не имеет почти никаких издержек помимо умножения и дополнения и потому что строки являются упакованными данными, которые будут когерентными в кэше.

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

Попытайтесь сделать некоторое исследование направленным на тип использования и алгоритмов, которые Вы используете. Это специально важно, если матрица является очень большой, так как неудачные обращения в кэш могут повредить Вашу производительность путем больше, чем необходимость в 1 или 2 дополнительных математических операциях для доступа к каждому адресу.

1
ответ дан 6 December 2019 в 05:49
поделиться

Очень вероятно это - проблема местности ссылки. vector использование new выделить ее внутренний массив, таким образом, каждая строка будет, по крайней мере, немного независимо в памяти из-за заголовка каждого блока; это могло быть большое расстояние независимо, если память уже фрагментируется при выделении их. Различные строки массива, вероятно, по крайней мере, подвергнутся отказу строки кэша и могли подвергнуться отсутствию страницы; если Вы действительно неудачны, две смежных строки могли бы быть на строках памяти, которые совместно используют слот TLB, и доступ к тому выселит другой.

По контрасту Ваши другие решения гарантируют, что все данные смежны. Могло помочь Вашей производительности при выравнивании структуры, таким образом, это пересекает как можно меньше строк кэша.

vector разработан для массивов изменяемого размера. Если Вы не должны изменять размер массивов, используйте регулярный массив C++. Операции STL могут обычно воздействовать на массивы C++.

Действительно обязательно обойдите массив в корректном направлении, т.е. через (последовательные адреса памяти), а не вниз. Это уменьшит отказы кэша.

7
ответ дан 6 December 2019 в 05:49
поделиться

Я сделал это некоторое время назад для необработанных изображений, объявив свои собственные классы двумерных массивов.

В обычном 2D-массиве вы получаете доступ к таким элементам, как:

array [2] [3]. Теперь, чтобы получить этот эффект, у вас будет массив классов с перегруженным [] метод доступа к массиву. Но это, по сути, вернет другой массив, тем самым давая вы второе измерение.

Проблема с этим подходом состоит в том, что у него накладные расходы на двойной вызов функции.

Я использовал перегрузку стиля ().

Так что вместо array [2] [3], изменить я сделал это в стиле array (2,3).

Эта функция () была очень маленькой, и я убедился, что она встроена.

См. Общую концепцию по этой ссылке: http://www.learncpp.com/cpp-tutorial/99-overloading-the-parenthesis-operator/

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

Трудно объяснить без кода, но, по сути, результат был таким же быстрым, как и C, и намного проще для понимания и использования.

0
ответ дан 6 December 2019 в 05:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: