Болталка PascalABC.NET

  • Новичками могут оказаться и школьные учителя, например, которые уж далеко не школьники и не студенты.
  • Новичок в PascalABC.NET вовсе не то же, что новичок в программировании (см. выше).
  • Новичков нужно тоже уважать, а не рассчитывать, что им понравится читать замусоренные и косноязычные текстовки
  • Вы хоть одну книгу видели для школьников или студентов с жаргоном? Наоборот, детей и молодежь стараются приучать любыми способами к нормальной литературной речи, чтобы они могли общаться не таким языком, как в пивнушке.

Вот, для примера, только что на другом ресурсе прочитал вопрос;

Может ли, кто написать динамику по профилю с объяснением.
Задача: [пропущено мной]
Программу писать на крестах

Нормально, да? А у меня вырисовывается картинка: малолетка, который не в состоянии написать простенькую задачку (она действительно там примитивная), решил изложить проблему на языке, как ему кажется, “крутых прогеров”, чтобы все подумали, что на самом деле он почти профи, но вот как-то с этой задачкой “не срослось”. Конечно, не стану я ему помогать… - единственное, чего он добился своим глупым жаргоном.

P.S. Кто не понял этой белиберды - перевожу на нормальный язык: для обучения на профильном уровне школы требуется написать программу на С++ с использованием динамического программирования.

А вы считаете что им понравится читать слова которые они не знают?

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

Жаргон, (точнее, арго) уместен в общении меж собой в узкопрофессиональных группах. Собственно, потому он и арго. Чего спорить-то, вам уже и @Admin все объяснил, а Вы все за свое пытаетесь держаться. Не по-взрослому это, по-детски как-то.

НЕ знают - объясните. Я вот не погнушался к NumLibABC написать Руководство, где есть все нужные пояснения, быть может, даже местами не относящиеся к программированию.

Нужно уважать свою аудиторию, иначе она в ответ не станет уважать Вас.

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

А где оно кстати? На форуме видел, но в папке PABCWork.NET не находит.

Разработчики поместили его в папку \Doc области установки PascalABC.NЕТ

Тип int32 - это не тип PascalАВС.NЕТ Не понимаю, для чего ссылаться на внешние типы данных, если есть в языке свои синонимы: Тоже ведь “сишная” привычка.

Интересно… В C нет собственного String, а подключаемые библиотеки не используют синонимы стандартных типов. Как там такое может быть мне не понятно.

Поддерживаю. Это тип PascalABC.NET :smile: Но в любом случае, запомнить систематическую систему типов гораздо проще, чем систему, предлагаемую ЯП (в том числе и C).

Int16, Int32, Int64

против

smallint, integer, Int64

Не надо пользоваться опиской. Откройте Справку и найдите там int32 - где говорится, что это тип PascalABC.NЕТ ?

Видите ли, то, что Вам “проще запомнить” вовсе не означает, что это распространяется на всех ))

Это тип .NET. PascalABC.NET - это язык для данной платформы. Я не пойму, что Вас смущает?

Меня “смущает”, что когда говорят о конкретном языке, не принято использовать терминологию, лежащую вне его. Мне, к примеру, некомфортно сидеть и заниматься “переводом типов”. На будущее буду такие посты оставлять без внимания.

А массивы реализованы не конкретно в Паскале, а в .NET. Вот я и использую соответствующие типы. Возможно, я не объяснил причины использования типов .NET вместо Паскалевских синонимов. Дело в том, что при переводе программы в другой .NET - язык, использование специфических возможностей языка приводит к серьёзным затруднениям. Мне постоянно приходится переводить Паскаль в C# и обратно.

Да, но разве в указателях есть знак? Зачем он там?

Причем тут указатели? Забросьте Вы эту дурацкую сишную идеологию. Ну вот как вдолбили человеку когда-то этот С, - все, он обречен. Указатели - смысл всего. Пишите на ассемблере - будут указатели Вам сплошные.

А Вы что имели ввиду? И причём здесь вообще C?

Ну это Ваши проблемы, не так ли?

Мои. Но я ведь не предлагаю их кому-то.

На .Net обойти по производительности C++ - это как?)) Взять хотя бы массивы, которые при каждом доступе к элементу проверяют, не выходит ли индекс за границы. Это оптимизацией не назовёшь. А массивов для нейронной сети надо много… А доступов к их элементам - ещё больше.

С массивами можно работать и по указателям, причём Вы же мне и помогли разобраться, как это сделать. Обойти в прямом смысле слова нельзя, но можно оптимизировать алгоритм под конкретную задачу, а это можно сделать лишь имея все исходники(кроме самых базовых методов). Простой пример: есть динамическая библиотека Math.dll. В ней в классе Stepen объявлен метод НатСтепень(Число: Int32; Степень: Int32), возвращающий Int64. Я думаю, что единственный способ это реализовать следующий:

Library Math;
{$Reference 'System.dll'}
Uses System;
  Type Stepen=Static Class
    Public Static Function НатСтепень(Число: Int32; Степень: Int32): Int64;
    Begin
      Result:=Число;
      For Var i:=0 to Степень-1 do
         Result*=Число;
    End;
  End;
End.

В своей программе Вы подключаете библиотеку и используете вышеописанный метод, ведь это так удобно, метод универсальный, любую степень подписал и всё. Допустим, Вам нужно возвести в 4 степень массив из 100 чисел. Если использовать библиотеку, то получим это:

{$Reference 'Math.dll'}
{$Reference 'System.dll'}
Uses Math;
Uses System;
Procedure ArrMul(arr: array of Single);
Begin
  For Var i:=0 to arr.Length-1 do
    arr[i]:=Stepen.НатСтепень(arr[i], 4);
End;
Begin
  Var a:=new Single[100];
  ArrMul(a);
End.

В принципе, всё хорошо… Или нет? Смотрим: у нас степень, всегда одна и та-же (4), причём совсем небольшая. Зачем использовать цикл для вычисления этой степени(библиотека Math)? Мы ведь с лёгкостью можем написать в программе это:

For Var i:=0 to arr.Length-1 do
Begin
  Var Temp: Single:=arr[i];
  arr[i]*=Temp;
  arr[i]*=Temp;
  arr[i]*=Temp;
End;

Что мы сделали? Очень много. Во-первых, мы “размотали” цикл, убрав таким образом как минимум инкрементацию счётчика и проверку на его соответствие параметру. В конкретно этом примере, это особой погоды не сделает, однако если у нас это место будет повторяться, скажем, 1000000 раз(а такое частенько бывает в нейросетях), то разница будет более чем существенная. Второе: мы отказались от использования метода НатСтепень, и, таким образом, избавились от безусловного перехода(вызова метода), который, являясь одной из команд процессора, требует времени и ресурсов. В итоге, от библиотеки, которая вполне может быть написана на C++ не осталось и следа, а наша программа имеет все шансы превзойти по скорости и потребляемой памяти версию с библиотекой. Это лишь малая часть. Рекомендую почитать следующую статью с Хабра: https://habr.com/post/165729/. Там подробно описаны приёмы оптимизации .NET приложений, кроме того есть результаты тестов, показывающие, что эти ребята переплюнули всех конкурентов, использующих C++. Одним словом - библиотеки предназначены для различных вариантов, то есть их методы или классы сделаны так, чтобы обеспечить максимальную гибкость и простоту при разработке, например, тот-же метод возведения в степень. Он, находясь в библиотеке, достаточно гибок, позволяет возводить в различные степени. Но за гибкость метода (как, в общем-то, и за красивую реализацию), как правило, приходится платить его эффективностью. Ваш пример с массивом правильный. Я пробовал(а теперь и использую) работать с элементами по указателям. Могу сказать только одно: ракообразность указателей с лихвой компенсируется скоростью. Особенно это касается Bitmap’ов(ускорение во много раз).

Во первых, я взял за основу уже готовую “обёртку” из проекта, где есть и dll (толи 1.3 толи 1.4)

Потом доделал её до версии 1.6, так как для неё был рецепт компиляции без ошибок

Ну компилировалась она часа два. Тут можно конфигурировать под конкретный процессор, убрать зависимости от Python … но как выяснилось, всё это не очень нужно - там в ссылке в статье в моём предыдущем комментарии сказано, что можно просто инсталлировать tensorflow под python и переименовать одну из библиотек, которая на самом деле и есть “замаскированная” tensorflow.dll. Там правда есть привязки к python, но в Delphy4Tensorflow они тоже могут использоваться, когда из Pascal ещё и сам Python используется как скриптовый движок.

Если же использовать простую обёртку, с которой я начал, то программы выглядят слишком сложно, вот например перевод Hello TensorFlow:

program TensorFlowHello;

{$IFDEF FPC}
  {$MODE Delphi}
{$ENDIF}
// Pascal with c API implementation of python Hello:
// import tensorflow as tf
// hello = tf.constant('Hello, TensorFlow!')
// sess = tf.Session()
// print(sess.run(hello))

uses tensorflow;
type
  ByteArray = packed array of byte;
  PByteArray = ^ByteArray;
  TFString = packed record
    Aux : size_t;
    Data : shortstring;
  end;
  PTFstring = ^TFString;

var
  graph : pTF_Graph;
  options : pTF_SessionOptions;
  status : pTF_Status;
  session : pTF_Session;
  sHello : PChar = 'Hello, TensorFlow!';
  tensor,tensorOutput : pTF_Tensor;
  operationDescription : pTF_OperationDescription;
  operation : pTF_Operation;
  output : TF_Output;
  P : PTFString;
  SLen,SEncLen : size_t;



begin
  graph := TF_NewGraph;
  options := TF_NewSessionOptions;
  status := TF_NewStatus;
  session := TF_NewSession( graph, options, status );
  SLen := StrLen( sHello );
  SEncLen := TF_StringEncodedSize(SLen);
  tensor := TF_AllocateTensor( TF_STRING, 0, 0, 8 + SEncLen );
  operationDescription := TF_NewOperation( graph, 'Const', 'hello' );

  P :=  TF_TensorData( tensor );
  P^.Aux := 0;
  TF_StringEncode( sHello, SLen, @P^.Data, SEncLen, status );


  TF_SetAttrTensor( operationDescription, 'value', tensor, status );
  TF_SetAttrType( operationDescription, 'dtype', TF_TensorType( tensor ) );
  operation := TF_FinishOperation( operationDescription, status );

  output.oper := operation;
  output.index := 0;

  TF_SessionRun( session, 0,
                 0, 0, 0,  // Inputs
                 @output, @tensorOutput, 1,  // Outputs
                 @operation, 1,  // Operations
                 0, status );
  Writeln('Status code=',TF_GetCode( status ));
  P := TF_TensorData( tensorOutput );
  Writeln(P.Data);
  TF_CloseSession( session, status );
  TF_DeleteSession( session, status );
  TF_DeleteStatus( status );
  TF_DeleteSessionOptions( options );

  readln;
end.


1 лайк

Ну у Паскаля/Delphi уже была одна Алиса (бот)

http://alicebot.sweb.cz/introduction.html