powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Языки программирования семейства Pascal [закрыт для гостей] / Заметки о Делфи.
Модераторы: s62
17 сообщений из 42, страница 2 из 2
Заметки о Делфи.
    #965853
s62
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор темы
В свежей Delphi 12.2 появился класс TParallelArray.

Из записи в блоге. https://blogs.embarcadero.com/faster-delphi-rtl-with-parallel-arrays-and-ordered-dictionaries/
Код: Delphi
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
program ParallelArray;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  System.Classes,
  System.Generics.Collections,
  System.Threading,
  System.Diagnostics;

var
  A1, A2: array of Integer;
  I: Integer;
  T: TStopwatch;

begin
  try
    SetLength(A1, 100_000_000);
    SetLength(A2, 100_000_000);
    for I := 0 to High(A1) do
    begin
      A1[I] := Random(MaxInt);
      A2[I] := A1[I];
    end;

    // Warm up thread pool
    TTask.Create(
      procedure
      begin
        // empty
      end).Start;

    // Serial sorting
    T := TStopwatch.StartNew;
    TArray.Sort<Integer>(A1);
    T.Stop;
    Writeln('TArray.Sort: ', T.Elapsed.ToString);

    // Parallel sorting
    T := TStopwatch.StartNew;
    TParallelArray.Sort<Integer>(A2);
    T.Stop;
    Writeln('TParallelArray.Sort: ', T.Elapsed.ToString);
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  Readln;
end.
Цитата 
[игнорируется]
If I run it on my main computer, an Intel(R) Core(TM) i7-10700 CPU @ 2.90GHz , I get the following results, a nice 585% improvement! (output trimmed to milliseconds for readability)
Код: Delphi
1.
2.
TArray.Sort: 00:00:16.414
TParallelArray.Sort: 00:00:02.889
Я и не знал, что при помощи класса TArray из System.Generics.Collections можно так сортировать массивы. Там еще есть вот такая сортировка:
Код: Delphi
1.
class procedure Sort<T>(var Values: array of T; const Comparer: IComparer<T>); overload; static;
...
Изменено: 03.10.2024, 11:04 - s62
Рейтинг: 0 / 0
Заметки о Делфи.
    #1019961
s62
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор темы
Видел, как человек пользовался, но как-то сам не обращал внимания. Удобная вещь вверху окна редактора кода - два выпадающих окна, в левом список классов, в правом - список методов выбранного класса. И, как я понял, в нем же, если класс не выбрано - список процедур/функций (не методов классов) этого модуля.
А я всё пользовался поиском и переходом к объявлению (Ctrl+Click). Есть ещё конечно боковое окно структуры модуля, но я им редко до сих пор пользовался, обычно, когда какой-то чужой модуль открывал и искал какие-то классы, методы и т.п., так, оно у меня обычно свернуто.
В одном из текущих проектов есть большие модули с большими классами, где много методов, там эта штука удобна наверное. Всё, сейчас после обеда попробую использовать это.

p.s. Это - часть того, что называется Navigation toolbar, появилось, оказывается в Delphi XE8, я пользовался из этой панели (тулбара) переходом к разным секциям модуля.
https://docwiki.embarcadero.com/RADStudio/Athens//en/Code_Editor#Navigation_Toolbar
...
Изменено: 18.10.2024, 12:15 - s62
Рейтинг: 0 / 0
Заметки о Делфи.
    #1336960
s62
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор темы
Модуль Sysutils.
Код: Delphi
1.
EProgrammerNotFound = class(Exception);
Пояснения от Аллена Бауэра есть тут: https://stackoverflow.com/questions/2084120/eprogrammernotfound-exception-in-delphi
...
Рейтинг: 0 / 0
Заметки о Делфи.
    #1366991
s62
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор темы
Столкнулся с небольшим багом в версии 12.2. Запостил в соответствующий раздел сайта Эмбаркадеро (Quality portal). Сегодня поставили статус, что пофиксили в версии 12.3. Но из-за санкций сейчас в РФ нельзя купить и нельзя продлить подписку на Delphi. А у нас кончилась в конце прошлого ноября. Обновления на сайте Эмбаркадеро доступны для клиентов с активной подпиской. Ну, баг не очень серьезный, есть обход.
...
Изменено: 27.03.2025, 14:03 - s62
Рейтинг: 1 / 0
Нравится: Гарыныч
Заметки о Делфи.
    #1421932
s62
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор темы
Один из недостатков языка Delphi (Object Pascal) - что интерфейсы (интерфейсные типы) изначально были привязаны к технологии COM и по-умолчанию в них релизован подсчет ссылок и автоматическое удаление, когда ссылок становится ноль. Это усложняет использование интерфейсов как просто контрактов, как они например широко используются в Java. Например вы создаете обычным образом объект, который реализует какой-то интерфейс, потом когда-то собираетесь объект удалить. Но если вы обратились к нему через интерфейс, то как только ссылка на интерфейс выйдет из сферы видимости, компилятор сразу сам удалит этот объект.
Вот статья на эту тему. https://www.codeproject.com/Articles/1252175/Fixing-Delphis-Interface-Limitations
У меня один объкет создает другой, а этому другому нужно вызвать методы первого. Получается круговая ссылка (circular reference), Почитал, как такие ситуации разрешают, ИИ от гугла написал несколько вариантов. Один из них, первый объект реализует некий интерфейс, а второй обращается к этому интерфейсу, а не к самому первому объекту. Но особенности интерфейсов в Delphi делают этот метод геморным, неподходящим в общем.
Сейчас у меня это решено так, что объявлен процедурный тип (процедура объекта) и в конструктор второго объекта передаются три параметра этого типа (т.е. три метода первого объекта). Т.е. второй объект не должен что-либо знать о первом классе, ему достаточно знать тип параметра. Можно наверное и как-то иначе разрешить эту ситуацию, но не придумал, как это сделать.
А если бы интерфейсы были бы без reference counting, сделал бы интерфейс с этими тремя методами, он как раз и в других ситуациях пригодился бы. Мне надо из других модулей (и потоков) запускать в модуле определенного типа (и потоке) два типа действий и останавливать их оба одной и той же процедурой "стоп". Причем запускать могут разные модули. Интерфейс по-моему был бы к месту здесь.
...
Изменено: 29.05.2025, 13:22 - s62
Рейтинг: 0 / 0
Заметки о Делфи.
    #1421963
defecator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
[игнорирует гостей]
s62  29.05.2025, 13:19
[игнорируется]
Один из недостатков языка Delphi (Object Pascal) - что интерфейсы (интерфейсные типы) изначально были привязаны к технологии COM и по-умолчанию в них релизован подсчет ссылок и автоматическое удаление, когда ссылок становится ноль. Это усложняет использование интерфейсов как просто контрактов, как они например широко используются в Java. Например вы создаете обычным образом объект, который реализует какой-то интерфейс, потом когда-то собираетесь объект удалить. Но если вы обратились к нему через интерфейс, то как только ссылка на интерфейс выйдет из сферы видимости, компилятор сразу сам удалит этот объект.
Вот статья на эту тему. https://www.codeproject.com/Articles/1252175/Fixing-Delphis-Interface-Limitations
У меня один объкет создает другой, а этому другому нужно вызвать методы первого. Получается круговая ссылка (circular reference), Почитал, как такие ситуации разрешают, ИИ от гугла написал несколько вариантов. Один из них, первый объект реализует некий интерфейс, а второй обращается к этому интерфейсу, а не к самому первому объекту. Но особенности интерфейсов в Delphi делают этот метод геморным, неподходящим в общем.
Сейчас у меня это решено так, что объявлен процедурный тип (процедура объекта) и в конструктор второго объекта передаются три параметра этого типа (т.е. три метода первого объекта). Т.е. второй объект не должен что-либо знать о первом классе, ему достаточно знать тип параметра. Можно наверное и как-то иначе разрешить эту ситуацию, но не придумал, как это сделать.
А если бы интерфейсы были бы без reference counting, сделал бы интерфейс с этими тремя методами, он как раз и в других ситуациях пригодился бы. Мне надо из других модулей (и потоков) запускать в модуле определенного типа (и потоке) два типа действий и останавливать их оба одной и той же процедурой "стоп". Причем запускать могут разные модули. Интерфейс по-моему был бы к месту здесь.
что за недостаток ?
Наоборот, пиздатейшая вещь.
А для контрактов можно использовать обычные объекты, без интерфейсов
...
Рейтинг: 0 / 0
Заметки о Делфи.
    #1422200
s62
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор темы
defecator  29.05.2025, 13:49
[игнорируется]
А для контрактов можно использовать обычные объекты, без интерфейсов
То есть в моем случае взаимодействие осуществлять через вспомогательнный объект? Наверное да, можно, как вариант.
...
Рейтинг: 0 / 0
Заметки о Делфи.
    #1423232
s62
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор темы
Оказывается можно вот так:
Код: Delphi
1.
2.
3.
4.
5.
6.
7.
type
  TModeKind = (mkMeasure, mkOther, mkPause, mkAlarmMode, mkStSampleMeasure, mkWash); //fkAlarmMode - на него переходим при аварийной ситуации

var i: TModeKind;
begin
  for i := Low(TModeKind) to High(TModeKind) do
    ...
В документации написано
Цитата 
[игнорируется]
counter is a local variable (declared in the block containing the for statement) of ordinal type, without any qualifiers.
То есть обычно переменная цикла - целая, но это не обязательно, годится любой ordinal type, в том числе перечисляемый.
...
Изменено: 30.05.2025, 22:00 - s62
Рейтинг: 0 / 0
Заметки о Делфи.
    #1423233
Гарыныч
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
s62  30.05.2025, 21:59
[игнорируется]
Оказывается можно вот так:
Код: Delphi
1.
2.
3.
4.
5.
6.
7.
type
  TModeKind = (mkMeasure, mkOther, mkPause, mkAlarmMode, mkStSampleMeasure, mkWash); //fkAlarmMode - на него переходим при аварийной ситуации

var i: TModeKind;
begin
  for i := Low(TModeKind) to High(TModeKind) do
  ...
В документации написано
Цитата 
[игнорируется]
counter is a local variable (declared in the block containing the for statement) of ordinal type, without any qualifiers.
То есть обычно переменная цикла - целая, но это не обязательно, годится любой ordinal type, в том чсиле перечисляемый.
удобненько, это какой эмбаркадеро? 12-й?
...
Рейтинг: 0 / 0
Заметки о Делфи.
    #1423237
s62
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор темы
Гарыныч [игнорируется] 

Это 11, но вот это уже давно было. Не помню, раньше пользовался таким или нет.
...
Рейтинг: 0 / 0
Заметки о Делфи.
    #1423309
defecator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
[игнорирует гостей]
s62  30.05.2025, 21:59
[игнорируется]
Оказывается можно вот так:
Код: Delphi
1.
2.
3.
4.
5.
6.
7.
type
  TModeKind = (mkMeasure, mkOther, mkPause, mkAlarmMode, mkStSampleMeasure, mkWash); //fkAlarmMode - на него переходим при аварийной ситуации

var i: TModeKind;
begin
  for i := Low(TModeKind) to High(TModeKind) do
    ...
В документации написано
Цитата 
[игнорируется]
counter is a local variable (declared in the block containing the for statement) of ordinal type, without any qualifiers.
То есть обычно переменная цикла - целая, но это не обязательно, годится любой ordinal type, в том числе перечисляемый.
испокон веков в Паскале так было можно, потому что перечисление - это всего лишь целочисленная переменная,
а эти перечисления - всего лишь биты в этой переменной.

В современных дельфях можно указывать вот так
Код: Delphi
1.
2.
type
  TModeKind = (mkMeasure = 11, mkOther = 15, mkPause = 17, mkAlarmMode = 19, mkStSampleMeasure= 20, mkWash= 21);
Сейчас это 64-хбитный тип из коробки, а циферка обозначает установленный бит
...
Рейтинг: 0 / 0
Заметки о Делфи.
    #1423320
s62
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор темы
defecator  30.05.2025, 23:36
[игнорируется]
В современных дельфях можно указывать вот так
Код: Delphi
1.
2.
type
  TModeKind = (mkMeasure = 11, mkOther = 15, mkPause = 17, mkAlarmMode = 19, mkStSampleMeasure= 20, mkWash= 21);
Да, это я знаю и, насколько помню, даже использовал. Там, если задать первому элементу порядковый номер, а следующим не задавать, то они будут по порядку идти, начиная от первого (+1 и т.д.)
...
Изменено: 30.05.2025, 23:47 - s62
Рейтинг: 0 / 0
Заметки о Делфи.
    #1423345
s62
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор темы
defecator  30.05.2025, 23:36
[игнорируется]
испокон веков в Паскале так было можно
Я и не говорил, что это что-то новое. Просто по-моему раньше не пользовался (а может когда-то и пользовался).
...
Рейтинг: 0 / 0
Заметки о Делфи.
    #1423347
s62
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор темы
defecator  30.05.2025, 23:36
[игнорируется]
а эти перечисления - всего лишь биты в этой переменной.
Это ты наверное с множеством спутал. В переменной типа множества элементы как биты. А тут у переменной просто одно значение, да, оно хранится как целочисленное.
https://docwiki.embarcadero.com/RADStudio/Athens//en/Internal_Data_Formats_(Delphi)#Enumerated_Types
...
Изменено: 31.05.2025, 00:47 - s62
Рейтинг: 0 / 0
Заметки о Делфи.
    #1469243
s62
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор темы
Для оживления темы что ли.
Сам не пользуюсь обычно (не помню, может где-то и пользовался), но фича интересная.
Как известно, в ряде ЯП даже переменные простых типов суть объекты. Соответственно, у них могут быть методы.
В Delphi это не так.
Но, с помощью record helper'ов, как именно, я особо не разбирался, ряд функций и процедур для строк реализованы синтактически, как методы. При этом остаются старые варианты.

Например.
Код: Delphi
1.
2.
3.
4.
5.
6.
7.
8.
var
  s: string;
  Arr: TStringDynArray;
...
s := 'sdg/klertiu/qqqiii23nn/iiii';
Arr := Split(s, '/');
//или вот так
Arr := s.Split(['/']);
Вот набор методов для строк. Есть и для целых (там поменьше методов).
https://docwiki.embarcadero.com/Libraries/Athens/en/System.SysUtils.TStringHelper_Methods
...
Рейтинг: 0 / 0
Заметки о Делфи.
    #1469299
defecator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
[игнорирует гостей]
s62  23.07.2025, 15:50
[игнорируется]
Для оживления темы что ли.
Сам не пользуюсь обычно (не помню, может где-то и пользовался), но фича интересная.
Как известно, в ряде ЯП даже переменные простых типов суть объекты. Соответственно, у них могут быть методы.
В Delphi это не так.
Но, с помощью record helper'ов, как именно, я особо не разбирался, ряд функций и процедур для строк реализованы синтактически, как методы. При этом остаются старые варианты.

Например.
Код: Delphi
1.
2.
3.
4.
5.
6.
7.
8.
var
  s: string;
  Arr: TStringDynArray;
...
s := 'sdg/klertiu/qqqiii23nn/iiii';
Arr := Split(s, '/');
//или вот так
Arr := s.Split(['/']);
Вот набор методов для строк. Есть и для целых (там поменьше методов).
https://docwiki.embarcadero.com/Libraries/Athens/en/System.SysUtils.TStringHelper_Methods
Это отличная идея была, мне охуенно нравится.

Приходится иногда кодить в древних дельфях типа Delphi 5 или 7 - вот там заебёшься некотоорые очевидные и простые вещи реализовывать, которые уже 15 лет как сделаны в новых
...
Рейтинг: 1 / 0
Нравится: s62
Заметки о Делфи.
    #1507873
s62
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор темы
На одной фабрике в программе возникала вчера ошибка, в логе записи остались, но несколько секунд было, потом прошло. В процедуре, которая отображает в главном окне состояние устройств периодически. Ошибка - Access violation.

На всякий случай перечитал подсказки Gunsmoker'а из его большой статьи про обработку ошибок:
Цитата 
[игнорируется]
12). В случае EAccessViolation у нас есть два адреса: "Access violation at address 004564AA in module 'Project1.exe'. Read of address 00000000". Первый из них ("at address 004564AA") — это адрес проблемной инструкции. С ним можно поступить, как и в предыдущем пункте. Кроме него, в этом сообщении ещё интересны слова "Read" или "Write" и второй адрес ("of address 00000000"). "Read" указывает на то, что ваша программа пытается прочитать что-то из недоступной памяти (или, иногда, — выполнить), а "Write" — на то, что она пытается что-то записать. Это поможет вам проанализировать проблемную строчку — нужно анализировать только места чтения или только места записи в строке.

Далее, второй адрес в сообщении указывает, откуда/куда программа пытается читать или писать данные. Обычно это значение само по себе не очень полезно, однако из него тоже можно извлечь кой-какую информацию. Например, это значение может быть очень мало, например 00000000, 00000008 или 000000A1. В этом случае можно биться об заклад, что у вас какой-то объект равен nil, а вы пытаетесь с ним работать. Например, объект равен nil, и вы читаете/пишете его свойство. Или указатель на массив равен nil, а вы пытаетесь прочитать значение его ячейки. Откуда это следует — оставим вам в качестве домашнего задания :)

Если же это значение относительно велико, например 7FEB0010, 70000008 и т.п., то велики шансы, что у вас мусорная ссылка. Например, вы освободили объект, а потом позже пытаетесь к нему обратиться. Кстати, также велика вероятность, что эта ошибка — плавающая. Поэтому, если вы встретились с ней по время прогона под Delphi, не мешкайте — начинайте отлаживаться с места, а то потом можете и не повторить её. Для профилактики таких ошибок используйте процедуру FreeAndNil вместо метода Free, FreeMemAndNil вместо FreeMem или же явно обнуляйте все ссылки после освобождения объектов. Также, внимательно просмотрите свой код на предмет того, не используете ли вы где две ссылки на один и тот же объект. И если да, то обнуляете ли вы все ссылки при удалении объекта. Например, вы занесли объект в массив/список с автоосвобождением, и у вас есть ещё ссылка на объект.

Кстати, если второй адрес в сообщении с EAccessViolation совпадает с первым, то велика вероятность, что у вас ситуация с переходом выполнения программы по недействительному адресу (см. предыдущий пункт).
http://www.delphikingdom.com/asp/viewitem.asp?catalogid=1392

https://www.gunsmoker.ru/p/best.html#exceptions
...
Изменено: 29.08.2025, 14:14 - s62
Рейтинг: 1 / 0
Нравится: defecator
17 сообщений из 42, страница 2 из 2
Форумы / Языки программирования семейства Pascal [закрыт для гостей] / Заметки о Делфи.
Модераторы: s62
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]