Многоугольник, Fpc, Ооп, Оптимизация |
Многоугольник, Fpc, Ооп, Оптимизация |
Bokul |
26.12.2006 9:32
Сообщение
#1
|
Гуру Группа: Пользователи Сообщений: 1 117 Пол: Мужской Реальное имя: Богдан Репутация: 11 |
Реализовал объект многоугольник, который имеет неопределенное количество вершин. Но скорость работы с ним критическая, поэтому надо как можно сильнее его оптимизировать.
Вот, что он из себя представляет:
Кольцевой список
Модуль для работы с векторами
Программа для проверки минимальной работоспособности
Три модуля вмести: Polygone.rar ( 13.71 килобайт ) Кол-во скачиваний: 388 PS в принципе код прозрачен, но если что-то не понятно - спрашивайте. -------------------- Лао-Цзы :
Знать много и не выставлять себя знающим есть нравственная высота. Знать мало и выставлять себя знающим есть болезнь. Только понимая эту болезнь, мы можем избавиться от нее. |
volvo |
26.12.2006 9:59
Сообщение
#2
|
Гость |
Хм... Чего тут пока оптимизировать - непонятно... Я бы сделал версию со статистикой (причем, используя директивы {$IFDEF}, хорошая статистика она никогда не помешает, но надо, чтоб ее можно было отключать быстро, а не переписывать из-за этого пол-программы), сколько раз какая функция/метод вызывается (если пойти чуть дальше - сколько времени в среднем выполняется каждый метод), и запустил бы эту версию, скажем, для нескольких сотен ( может, тысяч, все зависит от того, сколько времени ты согласен ждать ответа программы ) полигонов, каждый из которых состоит из десятков/сотен вершин...
И вот когда программа тебе сообщит, что один метод вызывается 100 раз, а другой - 500000, ты будешь точно знать, на какой из них надо обращать внимание, а на какой - не очень... P.S. Цитата(Console) ... First contains second object Second is not inside first object Difference: -32768 Кстати, почему бы Increase/Decrease тоже не реализовать через ForEach? |
Bokul |
26.12.2006 19:32
Сообщение
#3
|
Гуру Группа: Пользователи Сообщений: 1 117 Пол: Мужской Реальное имя: Богдан Репутация: 11 |
Цитата Я бы сделал версию со статистикой (причем, используя директивы {$IFDEF}, хорошая статистика она никогда не помешает, но надо, чтоб ее можно было отключать быстро, а не переписывать из-за этого пол-программы) Да, правильно - так и надо, сделаем... Цитата (если пойти чуть дальше - сколько времени в среднем выполняется каждый метод) Как в Fpc засекать время? Цитата Кстати, почему бы Increase/Decrease тоже не реализовать через ForEach? Вообще то сначала они у меня были в виде перегруженных операторов (+-), но никак не получалось заставить их правильно работать - один из аргументов менял свое значение в независимости от того, как я его передавал в подпрограмму (оно и правильно, ведь если мы даже скопируем ссылку, данные расположенные по ее адресу останутся на месте). А почему без ForEach - для этого процедуре надо передавать еще один параметр - вектор, но ForEach работает только с таким типом ToDo=procedure(point:TPoint); PS volvo, где у тебя произошла такая утечка? -------------------- Лао-Цзы :
Знать много и не выставлять себя знающим есть нравственная высота. Знать мало и выставлять себя знающим есть болезнь. Только понимая эту болезнь, мы можем избавиться от нее. |
volvo |
26.12.2006 20:05
Сообщение
#4
|
Гость |
Цитата где у тебя произошла такая утечка? У меня? Я запустил только твою программу, буква в букву, как ты ее привел, так что утечка - у тебя... Цитата Как в Fpc засекать время? uses windows;Я думаю, этого будет достаточно, если сделать огромное количество вычислений... Можно, конечно, и поточнее время замерять, но с этим, я думаю, не стОит заморачиваться... Цитата А почему без ForEach - для этого процедуре надо передавать еще один параметр - вектор, но ForEach работает только с таким типом Ну, во-первых, перегрузку функций еще никто не отменял, ты не в TP, а в ObjectPascal-е, кстати, можно было бы и перегрузить, если, конечно, такие функции будут вызываться достаточно часто... А во-вторых,Цитата Вообще то сначала они у меня были в виде перегруженных операторов (+-), но никак не получалось заставить их правильно работать - показывай, как перегружал, у меня после добавления перегрузки operator + (const p: TPoint; const v: TVector) R: TPoint;в модуль UnitTVector вот такой код: procedure TPolygone.Decrease(Const Vector:TVector);отрабатывает без проблем... Кстати, это тебе хинт, как немного оптимизировать программу, вместо того, чтоб каждый раз брать List^.Last^.next, берешь его один раз, и сравниваешь с текущим значением P |
Bokul |
26.12.2006 20:22
Сообщение
#5
|
Гуру Группа: Пользователи Сообщений: 1 117 Пол: Мужской Реальное имя: Богдан Репутация: 11 |
Цитата У меня? Я запустил только твою программу, буква в букву, как ты ее привел, так что утечка - у тебя... И программу проверки мою??? Цитата показывай, как перегружал, у меня после добавления перегрузки Я не совсем то, что ты перегружал (в модуле Polygone они закомментированные):
Так Polygone менял свои значения вмести с R Цитата Как тебе такая запись ? Си напоминает. Цитата Кстати, это тебе хинт, как немного оптимизировать программу, вместо того, чтоб каждый раз брать List^.Last^.next, берешь его один раз, и сравниваешь с текущим значением P Спасибо! Только это скорее first чем last, это же связанный список и Last^.next указывает на первый элемент. -------------------- Лао-Цзы :
Знать много и не выставлять себя знающим есть нравственная высота. Знать мало и выставлять себя знающим есть болезнь. Только понимая эту болезнь, мы можем избавиться от нее. |
Bokul |
26.12.2006 21:28
Сообщение
#6
|
Гуру Группа: Пользователи Сообщений: 1 117 Пол: Мужской Реальное имя: Богдан Репутация: 11 |
Цитата И программу проверки мою??? Я имею ввиду при каких данных происходит такая утечка.. Есть вопросы по статистике: 1 При подключении модуля windows к модулю Polygone, наверное, проходит совмещения типов и компилятор начинает сердится на строку
2 Статистику надо собирать по каждой подпрограмме запускаемой во всех модулях? -------------------- Лао-Цзы :
Знать много и не выставлять себя знающим есть нравственная высота. Знать мало и выставлять себя знающим есть болезнь. Только понимая эту болезнь, мы можем избавиться от нее. |
volvo |
26.12.2006 21:41
Сообщение
#7
|
Гость |
Цитата Я имею ввиду при каких данных происходит такая утечка.. При твоих... Copy+Paste из твоего первого сообщения + Build + Run = (результат ты видел) Цитата При подключении модуля windows к модулю Polygone, наверное, проходит совмещения типов и компилятор начинает сердится на строку Берем бубен, 3 раза обходим вокруг компа, не забывая пропеть какую-нибудь песню, напоминающую песнь чукчи в тундре (не забудь, именно ТРИ раза!!!), потом снова садимся за компьютер, меняем местами названия модулей:unit Polygone; и смотрим, что будет... Цитата Статистику надо собирать по каждой подпрограмме запускаемой во всех модулях? Я бы собирал статистику по каждому методу в программе... Для всех объектов - при вызове метода увеличить счетчик, и все... Потом пригодится... Распечатаешь все счетчики - сразу увидишь, что НАДО оптимизировать, а что НЕТ...Если то же самое сделаешь со временем - будет еще лучше, возможно метод-то вызывается 10 раз, но пожирает при этом 80% времени - его и будем ускорять... |
Bokul |
26.12.2006 22:18
Сообщение
#8
|
Гуру Группа: Пользователи Сообщений: 1 117 Пол: Мужской Реальное имя: Богдан Репутация: 11 |
Цитата При твоих... Copy+Paste из твоего первого сообщения + Build + Run = (результат ты видел) Точно, почему я сам это не увидел Самое удивительное это что размер свободной области увеличивается -------------------- Лао-Цзы :
Знать много и не выставлять себя знающим есть нравственная высота. Знать мало и выставлять себя знающим есть болезнь. Только понимая эту болезнь, мы можем избавиться от нее. |
Bokul |
27.12.2006 7:50
Сообщение
#9
|
Гуру Группа: Пользователи Сообщений: 1 117 Пол: Мужской Реальное имя: Богдан Репутация: 11 |
Попытался добавить статистику, но как-то не сильно она хочет работать - надо суровую руку профи приложить..
Что я сделал: Добавил в объект ТPolygone поле Stat типа TAboutPol для хранения интересующей нас информации о каждом методе
Так как я не могу проверить в программе утечек (из-за проблемы, описанной в теме "Шаровая" оперативка ), то и все мои попытки избавление от них остались тщетными (а может их прсто нет? ), хотя при отладке модуля ListOfVertex ошибок, вроде, не возникало (отладка проделывалась также в Bp). Прога для тестирования - 4.rar ( 441 байт ) Кол-во скачиваний: 356 Статистика тоже хромает по непонятным для меня причинам: первый столбик (nomber) отвечает за количество вызовов каждого метода, но они должны быть разные - ведь метод ContainsPoint запускается каждый раз при выполнении ContainsOtherPolyg или IsInside. . Что еще интересно - я вижу (в Watches) как меняется переменная Stat.ContainsPoint.n при отладке, но получаю совсем другие результаты при выполнении!!! Искал ошибку целый день - безрезультатно . Присоединяю архив с добавленной статистикой для Polygone, модулем ListOfVertex, избавленным от нескольких багов и программу вывода статистики Polygone.rar ( 16.08 килобайт ) Кол-во скачиваний: 343 -------------------- Лао-Цзы :
Знать много и не выставлять себя знающим есть нравственная высота. Знать мало и выставлять себя знающим есть болезнь. Только понимая эту болезнь, мы можем избавиться от нее. |
volvo |
29.12.2006 13:01
Сообщение
#10
|
Гость |
Цитата Попытался добавить статистику, но как-то не сильно она хочет работать Чего-то ты переусложнил по-моему работу со статистикой... Смотри, как это же делал бы я:1. Пишем очень простой модуль: unit stat;Как видишь - ничего особенного, просто выделяем место для хранения статистики, и процедура для их печати 2. Пишем 2 очень маленьких файлика: before.inc begin и after.inc begin 3. Зачем? А вот зачем: теперь вместо конструкции вида: procedure TPolygone.ForEach(proc:ToDO);достаточно написать procedure TPolygone.ForEach(proc:ToDO);(понятно назначение тех двух переменных - я ввел их просто чтобы не описывать вот эти вои локальные переменные, и сэкономить этим на объеме текста)... А проверять {$ifdef StatisticPolygone} можно и внутри файлов before.inc/after.inc Переделал твою программу, добавив в нее свой модуль статистики - вот что получилось: Цитата(Console) ForEach: Number: 10000 Time: 15 Time for each: 0.001500 По-моему, больше похоже на правду... А насчет Difference я тебе уже сказал в другой теме, куда смотреть...Increase: Number: 10000 Time: 0 Time for each: 0.000000 Decrease: Number: 10000 Time: 15 Time for each: 0.001500 ContainsPoint: Number: 10000 Time: 47 Time for each: 0.004700 ContainsOtherPolyg: Number: 10000 Time: 0 Time for each: 0.000000 IsInside: Number: 10000 Time: 0 Time for each: 0.000000 methods calling: Init: count:: 10000 time:: 0 average:: 0.00000 siAddVertex: count:: 1000000 time:: 250 average:: 0.00025 siIncrease: count:: 10000 time:: 0 average:: 0.00000 siDecrease: count:: 10000 time:: 15 average:: 0.00150 siForEach: count:: 10000 time:: 15 average:: 0.00150 siContainsPoint: count:: 30000 time:: 47 average:: 0.00157 siContainsOtherPolyg: count:: 10000 time:: 0 average:: 0.00000 siInside: count:: 20000 time:: 0 average:: 0.00000 siDone: count:: 0 time:: 0 zero division Difference: -79872 |
Bokul |
29.12.2006 20:56
Сообщение
#11
|
Гуру Группа: Пользователи Сообщений: 1 117 Пол: Мужской Реальное имя: Богдан Репутация: 11 |
Цитата Смотри, как это же делал бы я: Красиво Единственный вопрос - как называется тип типа tstatindex? Цитата А насчет Difference я тебе уже сказал в другой теме, куда смотреть... Нашел утечку - как всегда дурацкая ошибка Вместо dispose(mas[i]); надо dispose(mas[i],done); Вот, какие данные получил я : Отчет heaprtc Цитата Heap dump by heaptrc unit 10100000 memory blocks allocated : 121200000/161600000 10100000 memory blocks freed : 121200000/161600000 0 unfreed memory blocks : 0 True heap size : 98304 (80 used in System startup) True free heap : 98224 Наверно ничего и не надо оптимизировать - ведь для нас критическими являются такие рабочие лошадки как ContainsPoint, ContainsOtherPolyg, Inside, а не AddVertex и Done, пожирающие почти все время, которые используются только при инициализации и в конце. -------------------- Лао-Цзы :
Знать много и не выставлять себя знающим есть нравственная высота. Знать мало и выставлять себя знающим есть болезнь. Только понимая эту болезнь, мы можем избавиться от нее. |
Текстовая версия | 13.06.2024 9:20 |