Pull to refresh
29
0
Геннадий Малинин @HemulGM

Программист Delphi

Send message

Ну, во-первых, если у клиента есть потребность в решении, то никто не запрещает тебе написать его на Delphi. Клиент быстро получит решение и будет доволен.

Во-вторых, много компаний которые не только используют Delphi, потому что кто-то когда-то им его создал и нужно допиливать, но и потому что создают новые решения на современном Delphi. Несмотря на все тенденции в языках, софт на Delphi создается очень быстро и требует меньше внимания в будущем, потому что нет никаких зависимостей. Я до сих пор могу на Win11 запустить софт на Delphi 20ти летней давности и он ни слова не обронит и будет без проблем работать.

Где-то 10 лет назад, я написал свой первый коммерчески-успешный продукт для одного заказчика. С тех пор, он обращался ко мне лишь несколько раз, первые два раза - это были баги в расчетах, которые нужно было поправить, и два раза были обращения на добавление новых фич. До сих пор этот софт у них работает. А программа была не простая. Там и бд и сложные расчеты и 3D моделирование. Это была программа для расчета огромных ящиков по ГОСТу с изменяющейся моделью в реальном времени, базой заказчиков и историей их заказов. Программа создавалась ещё для XP, но они сами без проблем установили её на Win10, а сейчас может уже и на Win11. Программа обошлась им где-то в 300к + 100к на две новые фичи, а пользуются они ею уже 10 лет. Насколько это выгодно? Особенно, если бы это было какое-то решение на Web. А я потратил на эту программу где-то 3 месяца (параллельно с основной работой) + неделя.

На текущем рабочем месте я стал инициатором создания нового софта на Delphi и использования современных версий языка. Под моим началом переписан бэкенд некоторых сервисов с Питона на Делфи, что решило много проблем с производительностью сервисов и сократило время на добавление новых фич сервиса (последнее вероятно просто связано с архитектурой).

Также, на работе я поспорил с тех. лидом, что напишу мобильное приложение для просмотра 3D панорам быстрее, чем наши разработчики на Unity. И написал. В итоге, именно моё решение сейчас находится в некоторых магазинах Леруа Мерлен.

Здесь скорее дело не в том, что тут математические операции поменялись местами, а в том, что у нас есть ограниченный набор регистров.

  1. cc:=c*c; dd:=d*d; d:=(c+c)*d+n; c:=cc-dd+m;

  2. dd:=d*d; d:=(c+c)*d+n; cc:=c*c; c:=cc-dd+m;

В первом варианте ты работаешь с "c" и "cc", а потом с "d" и "dd", а во втором, ты работаешь c "cc"/"c", потом с "c" и "d", потом c "d"/"dd". Т.е. у тебя лишний раз не перекладывается c/d при операциях и компилятор может оставить "c" в том же регистре для след. операции.

Когда ожидается введение begin/end?

Я видел на Win11 BSOD, у меня шлейф от SSD отошел =(

Я выхожу на винде с реального статического IP и что? Да, естественно через маршрутизатор. Но у меня постоянно проброшены насквозь десяток портов на мой комп и что? root.hemulgm.ru - вперед, ломай, я тут, буду ждать и наблюдать)

Вообще, я думаю, что целью была программа, которая ничего не тянет. Даже графику. Здесь нет ни канваса, ни енкодера для битмапа. Ничего вообще не подключено, кроме модуля, который подключен автоматически (System.pas).

program Project53;

{$APPTYPE CONSOLE}

const
  Width = 1024;
  Height = 1024;
  LineSize = Width * (4 * 15);
  absc: Extended = -1.96680095;
  ordi: Extended = 0.00000478;
  size: Extended = 0.00000014;
  q: array[0..254] of Byte = (234, 94, 198, 83, 178, 216, 183, 78, 41, 84, 119, 63, 211, 71, 123, 38,
    223, 73, 197, 249, 126, 227, 211, 5, 36, 36, 128, 5, 151, 2, 198, 166, 197, 181, 142, 52, 174, 151,
    244, 164, 255, 62, 173, 75, 21, 197, 126, 225, 130, 146, 244, 175, 86, 1, 180, 253, 198, 191, 50, 36,
    233, 200, 150, 221, 176, 73, 23, 161, 71, 224, 41, 69, 139, 245, 44, 40, 68, 45, 147, 127, 73, 39,
    156, 189, 191, 20, 19, 15, 27, 203, 206, 97, 156, 111, 189, 126, 87, 209, 209, 36, 23, 17, 15, 49,
    172, 58, 146, 65, 93, 214, 80, 80, 168, 177, 231, 81, 122, 75, 196, 189, 141, 185, 105, 138, 152,
    225, 171, 28, 120, 103, 29, 13, 140, 172, 20, 235, 214, 174, 237, 70, 179, 188, 127, 169, 40, 58,
    242, 93, 32, 252, 78, 13, 26, 221, 141, 178, 25, 171, 4, 79, 231, 137, 83, 113, 230, 88, 90, 124, 18,
    217, 194, 46, 236, 126, 32, 228, 103, 53, 206, 150, 28, 159, 237, 138, 83, 114, 58, 47, 176, 254,
    161, 177, 138, 24, 191, 38, 59, 225, 182, 112, 250, 39, 10, 47, 2, 96, 101, 93, 21, 116, 129, 117,
    172, 209, 145, 64, 95, 149, 223, 155, 65, 178, 142, 224, 92, 93, 159, 199, 116, 52, 178, 214, 192,
    230, 47, 198, 68, 75, 179, 0, 8, 220, 51, 69, 171, 81, 41, 95, 108, 20, 121, 18, 215, 15, 75);

var
  BMP: file;
  ScanLine: array[0..LineSize - 1] of Byte;
  Pallete: array[0..255] of array[0..3] of Byte;
  Header: array[0..13] of Longint = ($4D42, 0, 0, 1078, 40, 0, 0, $080001, 0, 0, 2834, 2834, 0, 0);

begin
  // Prepare bitmap
  Header[5] := Width;
  Header[6] := Height;
  var Pitch := Width;
  if Pitch and 3 <> 0 then
    Pitch := (Pitch + 4) and $FFFFFFFC;
  Pitch := Pitch * Height;
  Header[9] := Pitch;
  Header[1] := Header[9] + 1078;

  Assign(BMP, 'Mandelbrot.bmp');
  Rewrite(BMP, 1);
  BlockWrite(BMP, Header, 2);
  BlockWrite(BMP, Header[1], 52);
  for var i := 0 to 254 do
  begin
    Pallete[i][0] := Round(127 + 127 * Cos(2 * Pi * (i + 16) / 255));
    Pallete[i][1] := Round(127 + 127 * Sin(2 * Pi * (i + 16) / 255));
    Pallete[i][2] := q[i];
    Pallete[i][3] := 0
  end;
  for var i := 0 to 2 do
    Pallete[255][i] := 255;
  Pallete[255][3] := 0;
  BlockWrite(BMP, Pallete, 256 * 4);
  //
  var step: Extended := size / Width;
  for var Y := 0 to Height - 1 do
  begin
    var n: Extended := (ordi - step * (Height - 1) / 2) + Y * step;
    for var X := 0 to Width - 1 do
    begin
      var m: Extended := (absc - step * (Width - 1) / 2) + X * step;
      var c: Extended := m;
      var d: Extended := n;
      var t: LongInt := 4081;
      var cc: Extended;
      var dd: Extended;
      repeat
        cc := c * c;
        dd := d * d;
        d := (c + c) * d + n;
        c := cc - dd + m;
        Dec(t)
      until (t = 0) or (cc + dd > 1000000.0);
      if t = 0 then
        ScanLine[X] := 255
      else
        ScanLine[X] := t mod 255;
    end;
    BlockWrite(BMP, ScanLine, Pitch div Height);
    Write('Process: ', Y + 1, Chr(13));
  end;
  Close(BMP);
  Writeln('');
  Writeln('Done');
  Readln;
end.

Пролил чуть света, но все равно ничего не понятно)

chr(13) тут переводит каретку в начало, что позволяет затирать строку без очистки всего вывода

Kylix давно нет. И работы с другими средами тоже.

RAD Studio - среда для Delphi, имеет несколько компиляторов для разных платформ. Сама среда только по Винду. Сборка под разные платформы тоже из под винды. Используется llvm для сборки.

Из коробки и кроссплатформенный GUI фреймворк, он не нативный для платформы, а полностью кастомный. Т.е. если иметь один стиль, приложение будет одинаково выглядеть на всех устройствах.

Со времен Delphi 7, среда разработки развивается до сих пор. Сейчас Delphi - это полностью кроссплатформенный язык с штатным кроссплатформенным GUI фреймворком с возможностями не уступающими HTML+CSS и тем более WPF.

Другими словами, мы создаем и мобильные приложения (iOS, Android) и десктоп приложения (Win, Mac, Linux) и даже веб приложения (и фуллстек решения (UniGui, WebUI) и только фронтенд (TMS Web Core - трансляция в js) и бэкенд (тут очень много: MARS, mORMot, DMVC, Horse, ...)).

Под мобильные платформы есть и нативный фреймворк - FGX, сторонний, от нашего разработчика.

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

Можете зайти в мой профиль гитхаб и посмотреть некоторые решения https://github.com/HemulGM

Вас это может удивить, но на Delphi стабильный спрос, особенно в странах Бразилии, Индии, Германии и некоторых других. В России вообще находятся несколько разработчиков этого инструмента.

Тут не "свой HTML", это та же компонентная система. Есть форма, есть компоненты. Только компоненты могут иметь любое представление. Мы через второй дизайнер создаем вид нужного нам компонента. Фото в карточке может быть изначально откуда угодно. И я не понимаю что это за проблема.

Зачем мне править исходники? Для твой карточки можно использовать любой компонент. Базовый. Всё равно в карточке много полей нужно показать и картинку и т.д. Такого компонента точно не будет. В нем нет смысла.

Уже давным давно всё это не так работает, как раньше в VCL. Я на VCL уже лет 5 ничего не писал. А использую кроссплатформенный фреймворк в том же Delphi. Там парадигма схожая с html. Как я уже говорил, там те же компоненты, но на любой компонент можно использовать какое угодно представление (и на любой инстанс компонента тоже).

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

Вот пример

Слева список представлений из примитивов. Мы можем его сделать из чего угодно, в том числе из компонентов со своими представлениями.

Справа список с карточками. При создании мы указываем содержимое карточки, в том числе картинку откуда хочешь. Или вообще указать карточке другое представление и она будет выглядеть иначе.

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

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

Своё свойство добавить нельзя, только это и не нужно, управлять отображением можно не только через свойства (нет, не в рантайме, а в дизайнере).

Есть подход, где есть "компонент", а есть его "представление". Компонент обладает свойствами, конкретного элемента, например, кнопка, там важен текст, размеры, положение и т.д. А вид можно задать через специальный дизайнер, где ты управляешь тем, как кнопка будет выглядеть. Ты конструируешь вид кнопки из примитивов, у которых уже есть и скругления и прочее.

Равно как HTML+CSS. HTML код - основной каркас, css - представление.

В итоге, система компонентная, а вот ограничений нет.

Проблема не в компонентности. Не знаю как там javafx, но в vcl возможности контролов зависят от платформы. Т.е. не очень корректное сравнение с HTML. Однако, есть другой пример - fmx, там те же компоненты, только вот их вид зависит только от разработчика. Хочешь скругление - делаешь как в css, берешь и указываешь скругление. Компонент сам по себе не имеет этой возможности, а вот его представление не ограничено ни чем. В qt, кстати, примерно так же и даже ближе к HTML.

вы имеете ввиду не фактическую нагрузку на кучу, а количество ручных телодвижений

Да, так и есть.

Да, object на стеке, но к сожалению, он уже давно deprecated. Так что его лучше вообще не брать в расчет. По этому, в Делфи отсутствие создания class на стеке - недостаток. Многим этого не хватает для производительного кода. Да и внутри фреймворков этого не хватает. Представьте, что есть в фреймворке код отрисовки, в котором создаётся class для работы и после вычислений очищается. Это сильно сказывается на производительности.

Не противоречие. В Делфи больше управляемых типов. Строки, массивы, рекорды.

А record и object <> class. Разные возможности

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

Точно, я никогда не делал Hello World, сразу начал с GUI поделок

Вот мой калькулятор, который, правда, как обычно, перерос в комбайн

А потом я понял, что писать просто калькулятор не интересно и сделал так

Ага, я просто вырезал часть среды и сделал, так, чтобы компилировалась dll, а программа выполняла функцию calc из dll

Он тоже не нормальный. Например проблема с Delphi

1. SO.

Delphi вообще не показан в списке или показан как Pascal. Очевидно, его в принципе не включили в подсчет тегов на SO, в то время, как вопросы там именно с хештегом "Delphi", а не только "Pascal"

2. GitHub.

GitHub никак не отличает Delphi от Pascal, но пусть, не страшно. Но он его даже от C++ отличает не всегда. Например, все "inc" файлы по умолчанию он считает исходниками C++, в то время, как внутри них код Delphi (синтаксис паскаля). В итоге мы имеем проекты, которые GitHub считает C++, в то время, как там ни строчки нет на C++. И таких проектов на GitHub полно.

С другими языками очевидно то же самое в большинстве случаев

Information

Rating
5,216-th
Location
Екатеринбург, Свердловская обл., Россия
Date of birth
Registered
Activity

Specialization

Software Developer, Fullstack Developer
Senior
From 180,000 ₽
Delphi
SQL
Database
Git
REST
C#
Python
OOP
MySQL
PHP