Показаны сообщения с ярлыком XE4. Показать все сообщения
Показаны сообщения с ярлыком XE4. Показать все сообщения

среда, 3 июля 2013 г.

Померил потребление памяти в проектах под XE4

Померил потребление памяти в проектах под XE4.

"В среднем по больнице" - потребление памяти под нашими "стандартными" тестами - упало. ЗАМЕТНО.

А быстродействие - возросло. Не очень заметно правда, но возросло.

Так что - смысл в переходе - есть даже с этой точки зрения.

У меня в тестах есть параметр "общесистемное потребление памяти" - ну это та память, которую я лично не контроллирую. Это общесистемные библиотеки, VCL и сторонние компоненты. Так этот параметр УПАЛ на 50 (!) %.

четверг, 20 июня 2013 г.

Портирование на Delphi XE4 идёт вполне успешно

Портирование на Delphi XE4 идёт вполне успешно.

Всё меньше и меньше тестов не проходят.

Скорость работы правда существенно снизилась, так как я занимаюсь СОВСЕМ другими рабочими вопросами. Посему - портирую "в свободное от работы время".

ПРИНЦИПИАЛЬНЫХ сложностей не возникло, за исключением уже описанных ДВУХ ошибок - с открытыми массивами (http://18delphi.blogspot.com/2013/05/xe4.html) и "пустыми интерфейсами" (http://18delphi.blogspot.com/2013/06/blog-post_13.html).

С открытыми массивами - придумал workaround и жду update от Embarcadero (http://18delphi.blogspot.com/2013/05/resolved.html).

С интерфейсами - сложнее. Ошибка - плавающая. Пока "за хвост" - не поймал. Ловлю.

Ещё как-то странно себя ведёт TCanvas по сравнению с Delphi 7. Отдаёт ДРУГИЕ (немножко, буквально на пиксель) метрики шрифтов. И то - не всегда. Разбираться - пока не стал. Сделал для таких тестов ДРУГИЕ эталоны под XE4. По крайней мере - всё СТАБИЛЬНО работает в РАМКАХ новых эталонов. То есть - разница - систематическая, а не плавающая. Что УЖЕ радует. Если "ВДРУГ" будет "свободное время" - я конечно с этой разницей тоже поразбираюсь. Чисто из того, чтобы удовлетворить СВОЙ собственный интерес.

Пришлось ещё пока поправить "стандартные" ошибки VCL с которыми наши проекты - не живут (http://18delphi.blogspot.com/2013/06/embarcadero.html). Червь сомненья меня гложет - хочется сделать как-то по-другому. Без правки стандартного кода библиотек. Но я пока - не придумал как. Есть конечно опыт SuperVision и статьи от Багеля, про внедрение в код. Ну и "внерение в код" от ElPack/RX. Но я пока в этом - не очень силён. Всё ещё надеюсь придумать что-то менее хардкорное. Хотя бы "аккуратный" Cut'n'Paste на худой конец.

Серия про "ошибки" в VCL была тут - http://18delphi.blogspot.com/2013/04/vcl.html. Ну и рядом там. "Правки в VCL (N)".

Далеко не со всеми ПРИВЕДЁННЫМИ там правками наши проекты не живут. Но я уж привёл - ВСЕ известные правки. Так сказать "для полноты картины". Жаль, что нету "обратной связи"... Я думал - люди откликнутся... Начнут "бить ногами". Рассказывать, что "у меня руки кривые". Тишина... Тишина - она подозрительнее всего.

В общем - процесс идёт. Он пока не на "промышленной основе". Но идёт. Надеюсь, что всё будет удачно. И что и до 64-х бит - я тоже доберусь. А вот там - есть ВОПРОСЫ - http://18delphi.blogspot.com/2013/06/xe-64_7.html. ВОПРОСЫ - такие - СЕРЬЁЗНЫЕ. Что с НИМИ делать - ПОКА ВООБЩЕ - не знаю.

С правками VCL придумать бы что умное.... Чтобы не трогать стандартного кода.

Особенно вот этого:
procedure RegisterClass(AClass: TPersistentClass);
begin
  RegGroups.Lock;
  try
    while not RegGroups.Registered(AClass) do
    begin
      try
       RegGroups.RegisterClass(AClass);
      except {V}
       on E : EFilerError do
        if (Format(SDuplicateClass, [AClass.ClassName]) = E.Message) then
         // do nothing
        else
         raise;
      end;//try..except {/V}
      if AClass = TPersistent then Break;
      AClass := TPersistentClass(AClass.ClassParent);
    end;
  finally
    RegGroups.Unlock;
  end;
end;

"Хозяин кода" ведь в дом вернулся...

Ибо приведённый код - это ну совсем не ошибка. Хотя мне и не очень понятно - ЗАЧЕМ все родительские классы регистрировать. Ибо и без этого - вполне себе работает. Но! Это - ЗАТОЧКА, под "мои конкретные нужды" с "хоккеем" с примесями в компонентах. Мы правда всё равно от dfm скоро откажемся. В их классическом виде. Есть МНОГО насущных потребностей. Например - инстанцирование контролов в формах с разными классами реализации в зависимости от внешних условий. dfm это всё равно не позволяет. Ну и IfDef в dfm не бывает. А "очень хочется". Ну и про FireMonkey - есть у меня пара "шальных мыслей" - как "разом" проект с VCL перевести на FireMonkey. Опять же - через условное инстанцирование. Взять и "ловко подменить" VCL-ные контролы на контролы FM. И получить - ДВЕ ВЕРСИИ приложения - на VCL и на FM. Там конечно есть сложности, но они - решаемы. Наверное - максиму, что придётся - "выделять фасады". Как мне пока кажется. Это пока только в теории правда. Но я кое что - уже обкатал на практических примерах. В основном на VGScene правда. Но "окна - они и в африке окна". Про мультиплатформенность - пока вообще - НЕ ГОВОРЮ и НЕ ДУМАЮ. Пусть Delphi XE5 или XE6 выпустят :-) С их то темпами. Тогда - и буду думать. Я боюсь, что раньше - я всё равно не успею. Разве что только FM ОТДЕЛЬНО от РЕАЛЬНЫХ проектов опробовать. И всё таки - тесты написать.

пятница, 7 июня 2013 г.

Собрал один "микроскопический" проект под XE 64-бита

Собрал один "микроскопический" проект под XE 64-бита. Работает. Но появилось много вопросов - "что делать дальше".

Первый вопрос - что же делать со своими "лямбдами". Заменять на reference to function под IfDef? По всему коду?

Что делать с ассемблерными вставками? 64-битного ассемблера - я банально - НЕ ЗНАЮ. А уж особенностей компилятора и построения кода - так и подавно.

понедельник, 3 июня 2013 г.

Запустил сегодня проекты собранные под XE4

Придумал workaround бага компиляции. И запустил сегодня проекты собранные под XE4. Тесты показывают навскидку не худшие результаты, чем под XE3.

HashLittle не работает БЕЗ OverflowChecks Off

function HashLittle(const Data; Len, InitVal: Integer): Integer;
var
  pb: PByte;
  pd: PCardinal absolute pb;
  a, b, c: Cardinal;
label
  case_1, case_2, case_3, case_4, case_5, case_6,
  case_7, case_8, case_9, case_10, case_11, case_12;
begin
  a := Cardinal($DEADBEEF) + Cardinal(Len shl 2) + Cardinal(InitVal);
  b := a;
  c := a;

  pb := @Data;

  // 4-byte aligned data
  if (Cardinal(pb) and 3) = 0 then
  begin
    while Len > 12 do
    begin
      Inc(a, pd[0]);
      Inc(b, pd[1]);
      Inc(c, pd[2]);
      Mix(a, b, c);
      Dec(Len, 12);
      Inc(pd, 3);
    end;

    case Len of
      0: Exit(Integer(c));
      1: Inc(a, pd[0] and $FF);
      2: Inc(a, pd[0] and $FFFF);
      3: Inc(a, pd[0] and $FFFFFF);
      4: Inc(a, pd[0]);
      5:
      begin
        Inc(a, pd[0]);
        Inc(b, pd[1] and $FF);
      end;
      6:
      begin
        Inc(a, pd[0]);
        Inc(b, pd[1] and $FFFF);
      end;
      7:
      begin
        Inc(a, pd[0]);
        Inc(b, pd[1] and $FFFFFF);
      end;
      8:
      begin
        Inc(a, pd[0]);
        Inc(b, pd[1]);
      end;
      9:
      begin
        Inc(a, pd[0]);
        Inc(b, pd[1]);
        Inc(c, pd[2] and $FF);
      end;
      10:
      begin
        Inc(a, pd[0]);
        Inc(b, pd[1]);
        Inc(c, pd[2] and $FFFF);
      end;
      11:
      begin
        Inc(a, pd[0]);
        Inc(b, pd[1]);
        Inc(c, pd[2] and $FFFFFF);
      end;
      12:
      begin
        Inc(a, pd[0]);
        Inc(b, pd[1]);
        Inc(c, pd[2]);
      end;
    end;
  end
  else
  begin
    // Ignoring rare case of 2-byte aligned data. This handles all other cases.
    while Len > 12 do
    begin
      Inc(a, pb[0] + pb[1] shl 8 + pb[2] shl 16 + pb[3] shl 24);
      Inc(b, pb[4] + pb[5] shl 8 + pb[6] shl 16 + pb[7] shl 24);
      Inc(c, pb[8] + pb[9] shl 8 + pb[10] shl 16 + pb[11] shl 24);
      Mix(a, b, c);
      Dec(Len, 12);
      Inc(pb, 12);
    end;

    case Len of
      0: Exit(c);
      1: goto case_1;
      2: goto case_2;
      3: goto case_3;
      4: goto case_4;
      5: goto case_5;
      6: goto case_6;
      7: goto case_7;
      8: goto case_8;
      9: goto case_9;
      10: goto case_10;
      11: goto case_11;
      12: goto case_12;
    end;

case_12:
    Inc(c, pb[11] shl 24);
case_11:
    Inc(c, pb[10] shl 16);
case_10:
    Inc(c, pb[9] shl 8);
case_9:
    Inc(c, pb[8]);
case_8:
    Inc(b, pb[7] shl 24);
case_7:
    Inc(b, pb[6] shl 16);
case_6:
    Inc(b, pb[5] shl 8);
case_5:
    Inc(b, pb[4]);
case_4:
    Inc(a, pb[3] shl 24);
case_3:
    Inc(a, pb[2] shl 16);
case_2:
    Inc(a, pb[1] shl 8);
case_1:
    Inc(a, pb[0]);
  end;

  Final(a, b, c); <<----- падает тут
  Result := Integer(c);
end;

Вообще конечно комильфо было бы, если бы авторы предварили функцию директивой OverflowChecks Off.

пятница, 31 мая 2013 г.

Где-то за неделю перепортировал все проекты с XE3 на XE4

Где-то за неделю перепортировал все проекты с XE3 на XE4.

Они - СОБИРАЮТСЯ. Но пока ничего - НЕ РАБОТАЕТ из-за -http://18delphi.blogspot.com/2013/05/xe4.html

Жду теперь когда Resolved превратится в Closed.

P.S. я кстати нашёл ТРИ workaround'а ошибки. Попробую завтра всё же ЗАПУСТИТЬ простейшие тесты под XE4. РУКИ ЧЕШУТСЯ на это посмотреть.

пятница, 24 мая 2013 г.

!!! Падает простейший пример под XE4 !!!

http://qc.embarcadero.com/wc/qcmain.aspx?d=116040

Access Violation при запуске:

unit evFormats;

interface

type
  Tl3ClipboardFormat = Cardinal;
  Tl3ClipboardFormats = array of Tl3ClipboardFormat;

var
  evPlainTextFormats : Tl3ClipboardFormats = nil;
  evAllFormats : Tl3ClipboardFormats = nil;

implementation

uses
  Windows
  ;

function l3FormatArray(const anArray: array of Tl3ClipboardFormat): Tl3ClipboardFormats;
  {-}
var
 l_Len   : Integer;
 l_Index : Integer;
begin
 l_Len := Length(anArray);
 SetLength(Result, l_Len); // - вот тут ПАДАЕТ, да и отладчик показывает, что Result - Invalid
(* for l_Index := 0 to Pred(l_Len) do
  Result[l_Index] := anArray[l_Index];*)
end;

var
 cf_EverestBin : Tl3ClipboardFormat = 1;
 cf_EverestTxt : Tl3ClipboardFormat = 1;
 cf_RTF : Tl3ClipboardFormat = 1;
 cf_RTFLite : Tl3ClipboardFormat = 1;

initialization
 evPlainTextFormats := l3FormatArray([cf_UnicodeText, cf_Text, cf_OEMText]);
 evAllFormats := l3FormatArray([cf_EverestBin, cf_EverestTxt,
                                cf_RTF, cf_RTFLite,
                                cf_Bitmap,
                                cf_UnicodeText, cf_Text, cf_OEMText,
                                cf_hDrop]);

finalization
 evPlainTextFormats := nil;
 evAllFormats := nil;

end.


program tstXE4;

uses
  evFormats;

begin
end.

-------------------------------------
Достаточно даже вот так:


unit evFormats;

interface

type
  Tl3ClipboardFormat = Cardinal;
  Tl3ClipboardFormats = array of Tl3ClipboardFormat;

var
  evAllFormats : Tl3ClipboardFormats = nil;

implementation

uses
  Windows
  ;

function l3FormatArray(const anArray: array of Tl3ClipboardFormat): Tl3ClipboardFormats;
  {-}
var
 l_Len   : Integer;
 l_Index : Integer;
begin
 l_Len := Length(anArray);
 SetLength(Result, l_Len);
 for l_Index := 0 to Pred(l_Len) do
  Result[l_Index] := anArray[l_Index];
end;

var
 cf_EverestBin : Tl3ClipboardFormat = 1;
 cf_EverestTxt : Tl3ClipboardFormat = 1;

initialization
 evAllFormats := l3FormatArray([cf_EverestBin, cf_EverestTxt,
                                cf_UnicodeText, cf_Text, cf_OEMText,
                                cf_hDrop]);

finalization
 evAllFormats := nil;

end.
------------------------------------
!!!!

cf_EverestBin, cf_EverestTxt
заменяем на 1, 1
и - ВСЁ хорошо
по памяти ездят, когда "открытый массив" конструируют

Портят Result в l3FormatArray
---------
Даже вот так не падает:

 evAllFormats := l3FormatArray([cf_EverestBin, cf_EverestTxt,
                                cf_UnicodeText, cf_Text, cf_OEMText]);

P.S. мне кажется, что если были бы тесты - они бы это показали бы. Не такая уж редкая ситуация. Дарю Embarcadero - "первый тест". И в свою базу тестов это внесу.

P.P.S. Пока Embarcadero не поправит ошибку - буду окучивать XE3. Так что про XE4 видимо пока ничего не расскажу.

четверг, 16 мая 2013 г.

На что надо обратить внимание при портировании с Delphi 7 на Delphi XE3


1. String = WideString
PChar = PWideChar
Char = WideChar
– это - более чем весело (особенно PChar <> PByte, ведь ни для кого не секрет, что многие использовали PChar Не как "указатель на символ", а как "указатель на byte к которому применима адресная арифметика". Fail тут - обеспечен).
Я "тупо" взял и поменял всё это на AnsiString, PAnsiChar, AnsiChar. Поиском/заменой. А потом - поменял обратно - там где не собралось - в стандартных классах. Там где override. Типа KeyDown. Ну и естественно поменял - шаблоны кодогенерации.
2. FormatSettings - теперь запись с полями и методами. ShortDateFormat теперь равно FormatSettings.ShortDateFormat etc.
3. менеджер памяти - другой. Со всеми вытекающими. Кстати при ПРАВИЛЬНОМ подходе - позволяет найти много ошибок в старом коде "не сходя с места".
4. канва почему-то несколько по-иному себя ведёт
5. NativeInt etc. И их несовместимость с Integer и Cardinal. ДАЖЕ в 32 битах.
6. Часть функций API стали принимать/возвращать беззнаковые значения, вместо знаковых. И наоборот.
7. Записи по умолчанию на 8 байт выравниваются. Если вы использовали, что-то типа THackControl или записи на диск - тут надо быть внимательным.
8. Forms -> VCL.Forms etc.

Ну и ссылка от Embarcadero. Не совсем в тему, но полезная:
http://docwiki.embarcadero.com/RADStudio/XE4/en/Converting_32-bit_Delphi_Applications_to_64-bit_Windows

воскресенье, 28 апреля 2013 г.

Delphi Language для мобильной разработки

Изначальная ссылка тут - http://feedproxy.google.com/~r/Delphi2010ru/~3/b0xK9-SfJZ8/

http://embt.co/DelphiWP или вот - https://sourceforge.net/p/rumtmarc/code-0/HEAD/tree/trunk/Doc/delphilanguagemobiledevelopmentwhitepaper170413.pdf

Говорят "будет один строковый тип, с подсчётом ссылок и immutable". Ну в общем - знакомо. И в общем - правильно. Для сравнения - NSString и Il3CString. immutable! Ещё раз - это правильно. Атомарные объекты не должны менять своё состояние.

Только вот стратегию перехода ещё бы они более/менее правильную избрали бы. А не как с String/AnsiString/WideString. ShortSring vs. String - по-моему - помягче было. Или я забыл уж?

И zero-based. Т.е. индекс - с нуля, а не с единицы. Наконец-то! Я уж давно свой комплект функций написал.
Плавная замена API и RTL на helper'ы. Правильно в общем-то.

(+) - ARC - Automatic Reference Counting.

"In summary, reference counting is triggered as you assign an object to a variable and when a variable goes out of scope, regardless of the fact it is a local stack-based variable, a temporary one added by the compiler, or a field of another object. The same holds for parameters: When you pass an object as parameter to a function, the object’s reference count is incremented and when the function terminates and returns, it is decremented.
Note: Optimizing Parameters Passing: Exactly as it happens for strings, you can optimize parameters passing by using the const modifier. An object passed as a constant, doesn’t incur in the reference counting overhead. Given the same modifier can be used also on Windows, where it is useless, it is a good suggestion to update your code to use const object parameters, and const string parameters. Don’t expect a very significant speed improvement, though, as the reference counting overhead is very limited."

Слабые ссылки! Ну наконец то:

"A weak reference is a reference to an object that doesn’t increase its reference count. Given the previous scenario, if the reference from the second object back to the first one is weak, as the external variable goes out of scope, both objects will be destroyed.
Let’s look at this simple situation in code:
type
TMyComplexClass = class;
TMySimpleClass = class
private
[Weak] FOwnedBy: TMyComplexClass;
public
constructor Create();
destructor Destroy (); override;
procedure DoSomething(bRaise: Boolean = False);
end;
TMyComplexClass = class"

Интересно мне до кучи - додумались сделать СЛАБЫЕ ссылки на интерфейсы - или нет? Или надо продолжать "хоккей" с Pointer и приведением к нужному типу?

Ну и "синтаксический сахар". Перегрузка операторов для классов. Понятное дело, что она напрямую связана с подсчётом ссылок:
"3.8: BONUS FEATURE: OPERATOR OVERLOADING FOR CLASSES
There is a very interesting side effect of using ARC for memory management: the compiler can handle the lifetime of temporary objects returned by functions. One specific case is that of temporary objects returned by operators. In fact, a brand new feature of the new Delphi compiler is the ability to define operators for classes, with the same syntax and model that has been available for records since Delphi 2006."

"Смешение" интерфейсов и объектов (давно я об этом говорил):
"3.9: MIXING INTERFACES AND CLASSES
In the past, given that interface variable and standard object variables used different memory management models, it was generally suggested to avoid mixing the two approaches (like using an interface and an object variable or parameter to refer to the same object in memory).
With the new ARM compilers with ARC, the reference counting between object and interface variables is unified, so you can mix the two easily. This makes using interfaces more powerful and flexible on Delphi ARC platforms than it is on Delphi non-ARC platforms."

А вот это кстати ПРАВИЛЬНО:
"Sooner or later, the with statement is going to be deprecated and removed from the Delphi language. You can easily start removing it now from your code, and most Delphi developer will agree this is a good idea anyway, given some of the hidden pitfalls of this keyword."

with - давно напрашивается к убиению. Его бы на "переменные блока" заменить. Иначе с отрицательной устойчивостью - беда. Тот же Caption все наверное уже по сто раз не тому объекту присвоили.
------

Не удержусь. В целом всё это напоминает нашу библиотеку L3 - подсчёт ссылок, контейнеры, мапы, "юникодные"-строки. Файлеры те же кстати.

Ну и - "чем более кросс-платформенную вещь" вы хотите сделать, тем более сильно придётся "давать по рукам" собственным разработчикам.

-----
Update. Обзор от Gunsmoker'а - http://www.gunsmoker.ru/2013/05/modern-delphi.html

Приехал кстати ключ от Delphi XE4

Приехал кстати ключ от Delphi XE4. Быстро.

После отпуска буду глядеть.

вторник, 23 апреля 2013 г.

Жду теперь ключ к XE4

Жду теперь ключ к XE4. Как только приедет - опробую на тех проектах, которые уже были портированы на XE3.