Типы данных

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

Re: Типы данных

Сообщение Лекс Айрин » 23.12.2017 19:50:37

serbod писал(а):Объекты языка не тормозят, там самые тормоза только при выделении-освобождении мапяти.


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

Добавлено спустя 5 минут 14 секунд:
Cheb писал(а):Вот потому и тормозит, что примитивный, и кпд у него ниже плинтуса.
А не потому, что он - класс.


Не катит -- стандартный блокнот работает на порядки быстрее. И чем примитивнее код, тем быстрее он работает. Если, конечно, не использовать функции оптимизации поиска, но тут это не работает, т.к поиск/замена происходит линейно.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 4200
Зарегистрирован: 19.02.2013 16:54:51

Re: Типы данных

Сообщение vitaly_l » 24.12.2017 00:03:00

sign писал(а): 
GetMem(int64Ptr, 3 * SizeOf(Int64));
int64Ptr^ := 1;
  Inc(int64Ptr);
  int64Ptr^ := 22;
  Inc(int64Ptr);
  int64Ptr^ := 333;

Делайте лучше вот так:

SetLength(VInt64, 3);
  // Заполнение этих переменных значениями
  VInt64[0] :=   1;
  VInt64[1] :=  22;
  VInt64[2] := 333;


Почему SetLength лучше?
В смысле я понимаю что он удобнее, но почему лучше?
И что там крутого происходит с выделением памяти, нежели при GetMem?
Разве, SetLength, не делает "в тайне от программиста" GetMem?

И вообще, вот это (VInt64[0] :=   1; VInt64[1] :=  22; VInt64[2] := 333), у них загрузка значений, как работает в разжёванном виде?
Как вот эти хрени: [0], [1], [2] - превращаются в адреса памяти и как из них берётся содержимое, уж не через примитивный Inc() ли?

.
 
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41

Re: Типы данных

Сообщение Cheb » 24.12.2017 14:08:12

И чем примитивнее код, тем быстрее он работает.

Бред.
Прекращаю дискуссию.
Аватара пользователя
Cheb
энтузиаст
 
Сообщения: 631
Зарегистрирован: 06.06.2005 15:54:34

Re: Типы данных

Сообщение Лекс Айрин » 24.12.2017 20:03:19

Cheb писал(а):Бред.


Да ладно... еще ни один более "совершенный" код не работал быстрее. Более сложная обработка , соответственно больше кода, а следовательно и времени на его работу. Попробуй запустить старую игрушку на новом компе -- летать будет практически любая. Выглядеть, правда, будет хуже. Единственное, что спасает "отца русской демократии" это методы быстрого поиска данных, но они требуют индексации, которая тоже не бесплатна.

И любое сильное ускорение современных программ это ее примитивизация, заключающаяся, например, в выкидывании лишнего кода.
Да просто переход на более примитивную базу может сильно ускорить программу. Сложность разработки, правда, сильно возрастет... но на это люди идут уже сейчас, когда требуется реалтайм система.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 4200
Зарегистрирован: 19.02.2013 16:54:51

Re: Типы данных

Сообщение vitaly_l » 24.12.2017 20:07:39

Лекс Айрин писал(а):Да ладно... еще ни один более "совершенный" код не работал быстрее

Ещё больший бред, нежели бред, который идентифицировал Cheb.
Это не дискуссия - это констатация.
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41

Re: Типы данных

Сообщение Лекс Айрин » 24.12.2017 20:26:19

vitaly_l писал(а):Ещё больший бред, нежели бред, который идентифицировал Cheb.


Это практика данная нам в ощущениях. Например, для очень скоростной работы у меня есть старичок VC. Более того, некоторые программы у меня специально стоят в довольно стареньких версиях. И не зря я написал "совершенный" в кавычках. Есть более современный код, а есть более вычищенный. Это две большие разницы! Так что переход от TMemo к более сложным компонентам должен замедлять скорость работы, но этого не наблюдается... Следовательно, код TMemo просто не отлажен. Т. к. обычно наблюдается обратная зависимость (обычно все глобальные поиски/замены я делаю в блокнотах, т. к. просто реально 500+ замен могут подвесить офисный текстовый процессор, а у меня были случаи и 4000+), то это показывает недостаток конкретной реализации компонента сделанной будто бы для галочки.
Причем, т.к. метод замены не менялся, то весь остальной код тяжело считать "слабым звеном".
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 4200
Зарегистрирован: 19.02.2013 16:54:51

Re: Типы данных

Сообщение zub » 24.12.2017 21:51:45

Лекс Айрин, vitaly_l вы любой топик превращаете в бред. хорэ уже
zub
долгожитель
 
Сообщения: 2380
Зарегистрирован: 14.11.2005 23:51:26

Re: Типы данных

Сообщение Mirage » 13.02.2018 00:54:38

Cheb писал(а):Чёзабред, наследуешь от IUnknown, делая всё ручками, или от TInterfacedObject, где всё уже сделано за нас - и класс становится со счётчиком ссылок, автоудаляющийся при присваивании nil последней ссылке на него.


Не зависит семантика классовых ссылок от того, от чего там унаследован класс. Или где такое в документации написано?
Mirage
энтузиаст
 
Сообщения: 800
Зарегистрирован: 06.05.2005 20:29:07
Откуда: Russia

Re: Типы данных

Сообщение MylnikovDm » 13.02.2018 09:43:39

И вообще, вот это (VInt64[0] := 1; VInt64[1] := 22; VInt64[2] := 333), у них загрузка значений, как работает в разжёванном виде?
Как вот эти хрени: [0], [1], [2] - превращаются в адреса памяти и как из них берётся содержимое, уж не через примитивный Inc() ли?

Нет, адресация подобных элементов массива происходит через адрес плюс смещение, которое задано как константа при компиляции. А вот что будет работать быстрее зависит только от того, как тот и другой код обработает оптимизатор при компиляции.

У первого варианта могут быть дополнительные задержки, если после каждого inc результат будет сохранятся обратно в память, как оно, вообще-то, написано. Умеет ли оптимизатор компилятора FreePascal определять, что данное значение потом не используется и его можно не сохранять в память, это надо проверять.

У второго варианта каждый раз базовый адрес массива будет загружаться из памяти, а уже потом к нему будет прибавляться константа смещения. Опять же, это можно оптимизировать, если задействовать дополнительный регистр процессора для промежуточного хранения адреса смещения, но умеет ли оптимизатор компилятора делать такие вещи, это вопрос. Чисто теоретически, в данном случае можно было бы задействовать и inc, чтобы перемещаться по адресам массива, но я как-то сомневаюсь, что оптимизатор FreePascal будет делать столь сложный анализ, поскольку на практике такой код используется весьма редко.

А вообще, было бы интересно посмотреть, что там в обои случаях получается "в разжёванном виде"...
MylnikovDm
новенький
 
Сообщения: 88
Зарегистрирован: 15.02.2007 21:26:10
Откуда: Челябинск

Re: Типы данных

Сообщение Python » 11.03.2018 20:40:06

Лекс Айрин писал(а):Я не знаю, зачем нужен был вообще тип TObject, но тому кто это придумал но путаницы это прибавило знатно.

В чём разница написано в документации http://docwiki.embarcadero.com/RADStudi ... ts_(Delphi)
А вот для чего изобрели - тоже можно понять. Дело в том, что object располагается на стеке, если хочется разместить его в динамической памяти - то нужно будет ухитряться (для этого есть специальная форма процедуры New). Можно посмотреть обсуждение:
http://www.programmersforum.ru/showthread.php?t=203940
Там veniside более-менее внятно описал, в чём разница между object и class. Считается, что object - deprecated и его использование нежелательно, но это только потому что Borland переместила все фенечки object (например, методы) в record и радуется этому.
Базовые отличия:
- у всех class есть общий предок - TObject. У object общего предка по умолчанию нет, хотите - пишите руками.
- у всех class есть VMT и DMT, потому что их общий предок TObject имеет виртуальные методы (например, NewInstance, FreeInstance, Destroy). У object этого нет.
- все class помещаются в динамической памяти, object - это сами данные, при желании, их можно разместить в стеке, а можно - в динамической памяти. Кстати, придумав простенький object:
Код: Выделить всё
  TMan=object
  strict private
    fName:string;
    fBirth:TDateTime;
    function GetAge:integer;
  public
    property Name:string read fName;
    property Age:integer read GetAge;
    Constructor Init(const aName:string;Bd:TDateTime);
    Destructor Clear;
    function Full:string;virtual;
  end;

и поиграв с sizeof(TMan) можно убедиться, что если у метода Full убрать virtual - то объект станет на 4 байта меньше, что говорит о том, что VMT у него компилятор убрал за ненадобностью.
- все class обязаны создаваться конструктором, иначе - AV, или ещё какие гадости, при выделении памяти, она автоматически инициализируется нулями (если InitInstance не перекрыт, но я в жизни такого не встречал). object теоретически можно не создавать, потому что если он лежит на стеке, то память под него выделена. Тем не менее, значения полей у object будут случайными, а потому, лучше всё-таки его инициализировать. Лежащий на стеке object удаляет сам компилятор, заботиться об этом не нужно и это очень удобно. К сожалению, освобождается только память object, никаких деструкторов не вызывается, а это было бы так здорово...
- class может наследоваться только от class, object - только от object, никакое перекрёстное опыление между ними невозможно!
- у object не бывает published секции. То есть RTTI для него не генерируется.
Таким образом, object - это ООП "для нищих", а поскольку мы все уже "богатые" (с точки зрения памяти), то все и пользуемся class.
Примечание: в одном из своих проектов я столкнулся с жутким своппингом, выедал я порядка 400 Мб памяти, на машине было только два гигабайта, причём гигабайт был отожран всякими сервисами тапа антивируса, так что на всё про всё было всего один гигабайт. В связи с тем, что я парсил огромные файлы PCad (мегабайт по двадцать) и строил на базе прочитанного дерево, я решил, что можно сэкономить на памяти, если перейти с class на object. Был разработан менеджер object, чтобы можно было комфортно (с enumerator, чтобы перечисление со встроенным фильтром и прочими плюшками) и в итоге за несколько дней новая версия заработала. Удалось сэкономить на всё про всё около 5% используемой памяти. Своппинг по прежнему был жутким. Проблема полностью исчерпалась, когда на рабочее место поставили машину с 64-битной операционкой и 8 Гб памяти. Вместо полутора-двух минут та же программа без дополнительных доработок стала работать за 9 секунд!
Мораль сей басни такова: ставьте более мощное железо и да пребудет с вами Сила. Не пытайтесь на крохах экономить.
Python
новенький
 
Сообщения: 12
Зарегистрирован: 23.01.2018 21:50:17

Re: Типы данных

Сообщение vitaly_l » 11.03.2018 21:32:17

MylnikovDm писал(а):А вообще, было бы интересно посмотреть, что там в обои случаях получается "в разжёванном виде"...

Нет там ничего интересного, как и предполагалось, для setLength ассеммблерный код длиннее, чем для getMem.
:roll: Впрочем художники специально налажали кое чего в коде и поэтому getMem получилось вдвое короче (в цикле почти ~одинаково),
А узнать что именно там происходит в asm не удалось, т.к. закрыто хитрыми функциями
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41

Re: Типы данных

Сообщение Awkward » 11.03.2018 23:39:10

Ясно дело, GetMem будет короче, ведь этой функции не надо копировать /высвобождать дополнительно память, включая проверки managed типов (вроде String)
Awkward
незнакомец
 
Сообщения: 6
Зарегистрирован: 19.01.2017 00:06:47

Re: Типы данных

Сообщение MylnikovDm » 13.03.2018 11:36:14

Нет там ничего интересного, как и предполагалось, для setLength ассеммблерный код длиннее, чем для getMem.

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

Но мне было интересно не то, как работает GetMem или SetLenght, а то, каким образом компилятор обрабатывает чтение запись элементов массива. Так вот, исходя из тех листингов, что вы привели, однозначно следует, что работа со статическими массивами или прямыми указателями на область памяти работает быстрее, чем динамические массивы, так как при каждом обращении к динамическому массиву происходит дополнительное обращение к памяти для загрузки указателя на непосредственную область данных, в которой хранятся элементы массива. Таким образом получается, что динамические массивы и SetLength всегда будут работать медленнее, чем статические или через прямой указатель и GetMem.
MylnikovDm
новенький
 
Сообщения: 88
Зарегистрирован: 15.02.2007 21:26:10
Откуда: Челябинск

Re: Типы данных

Сообщение ElectroGuard » 13.03.2018 12:52:28

Таким образом получается, что динамические массивы и SetLength всегда будут работать медленнее, чем статические или через прямой указатель


Никто же не мешает сделать прямой указатель на динамический массив.
ElectroGuard
новенький
 
Сообщения: 70
Зарегистрирован: 03.06.2016 12:10:22

Re: Типы данных

Сообщение MylnikovDm » 13.03.2018 13:32:28

Никто же не мешает сделать прямой указатель на динамический массив.

А можете привести пример как можно в коде паскаля добраться до внутренних полей структуры описания динамического массива? Или вы предлагаете везде, где это требуется, делать ассемблерную вставку?
MylnikovDm
новенький
 
Сообщения: 88
Зарегистрирован: 15.02.2007 21:26:10
Откуда: Челябинск

Пред.След.

Вернуться в Free Pascal Compiler

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2

Рейтинг@Mail.ru