powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Fast Report - апострофы в переменных
84 сообщений из 84, показаны все 4 страниц
Fast Report - апострофы в переменных
    #39956398
SDima55
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый вечер.
Может кто сталкивался с такой проблемой не могу понять или я что то не так делаю или звезды не так сошлись. Задаю переменную для отчета FastReport Report.Variables['TxtConcl']:='''' + FConclusion.Text + '''';

FConclusion: TStringList - задается в обычном Memo и передается в функцию формирования отчета

В отчете текст выводится в апострофах я не понимаю от куда они берутся пробовал удалять их при задании переменной тогда вылетает ошибка при формировании. И по моему в документации написано что переменные типа String задаются в двойных кавычках. При этом другие переменные в одну строку (без спец символов) выводятся нормально. Кто ни будь может посоветовать как от них избавиться и почему в обычной строке их нет а в строке с символами chr(10) + chr(13) появляются апострофы.

Пример:

'11111

222

333
'
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956407
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SDima55> пробовал удалять их при задании переменной
SDima55> тогда вылетает ошибка при формировании.

Текст ошибки и тип переменной покажи.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956416
_Den_Z_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SDima55

И по моему в документации написано что переменные типа String задаются в двойных кавычках. При этом другие переменные в одну строку (без спец символов) выводятся нормально.
'

Переменные отчета это выражения скрипта. Т.е. литералы в переменных указываться в соответствии с выбранным языком скрипта.
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956422
SDima55
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Гаджимурадов Рустам,
Memo19: error in expression: Expression expected
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956423
SDima55
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
_Den_Z_,
язык скрипта PASCAL
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956425
SDima55
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
_Den_Z_,

PascalScript
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956427
SDima55
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Гаджимурадов Рустам,
Переменные в FastReport Variants я переменной присваиваю String в TStringList свойство Text возращает string
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956438
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Что-то не припомню подобных проблем...

Можно посмотреть в сторону события OnGetValue и там заполнять нужное значение.
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956439
_Den_Z_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SDima55,
Нужно формировать соответствующий языку строковый литерал.
Код: pascal
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.
  function BuildStringLiteral(List: TStrings): String;
  const sLineBreak = '#13#10';
  var
    i, Sz, Len: Integer;
  begin
    if List.Count = 0 then
    begin
      Result := ''''+'''';
      Exit;
    end;
    Sz := 0;
    for i := 0 to List.Count - 1 do
     Inc(Sz, Length(List[i]) + 8);
    Dec(Sz, 6);
    SetLength(Result, Sz);
    Sz := 1;
    for i := 0 to List.Count - 1 do
    begin
      Result[Sz] := '''';
      Len := Length(List[i]);
      CopyMemory(@Result[Sz + 1], @List[i][1], Len * SizeOf(Char));
      Inc(Sz, Len + 2);
      Result[Sz - 1] := '''';
      if i < List.Count - 1 then
        CopyMemory(@Result[Sz], @sLineBreak[1], Length(sLineBreak) * SizeOf(Char));
      Inc(Sz, 6);
    end;
  end;
...
begin
  frxReport.Variables.Variables['Var1'] := BuildStringLiteral(s);
end;



Либо, как уже предложили, вместо переменных отчета использовать событие OnGetValue .
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956441
SDima55
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
_Den_Z_,

Это в скрипте рапорта функцию описывать или не посредственно в delphi
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956443
SDima55
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
_Den_Z_,
Дело в том что раньше все проекты делал на ReportBuilder недавно перешел на FastReport мне просто интересно это зависит от чего
в Memo строка типа String я ее присваиваю переменной Variant Report выводит апострофы но в других строках без спец символов не выводит? так и должно быть или чтото не так. Просто чтоб потом не задавь глупые вопросы.
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956444
_Den_Z_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SDima55,

Это код для Delphi.
Если вызов делается в скрипте, то можно просто объявить переменную там же с типом String и использовать ее имя в выражении текстового поля [ИмяПеременнойСкрипта].
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956446
_Den_Z_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SDima55,
Я уже объяснил выше. Переменные отчета это выражения, которые содержат сприпт. Там должно быть либо выражение, либо литерал.
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956448
SDima55
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
_Den_Z_,

Просто если это нормально то тогда надо выносить в свойство MemoView потому что часто бывает когда пользователь вводит некий текст в Memo и его хотелось бы увидеть без доп. кавычек. Я же язык скрипта поставил pascal. А так два дня парусь и понять не могу либо лыжи не едут или я ****й
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956451
_Den_Z_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SDima55,
Если передача параметра идет из кода приложения и хочется передавать именно через Report.Variables, то используйте функцию приведенную выше.

Если список формируется в скрипте, то проще использовать переменную скрипта в выражении(пример прицепил).
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956454
SDima55
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
[quot _Den_Z_#22131503]SDima55,
Нужно формировать соответствующий языку строковый литерал.
[src delphi]
function BuildStringLiteral(List: TStrings): String;
const sLineBreak = '#13#10';
var
i, Sz, Len: Integer;
begin
if List.Count = 0 then
begin
Result := ''''+'''';
Exit;
end;
Sz := 0;
for i := 0 to List.Count - 1 do
Inc(Sz, Length(List[i]) + 8);
Dec(Sz, 6);
SetLength(Result, Sz);
Sz := 1;
for i := 0 to List.Count - 1 do
begin
Result[Sz] := '''';
Len := Length(List[i]);
CopyMemory(@Result[Sz + 1], @List[i][1], Len * SizeOf(Char));
Inc(Sz, Len + 2);
Result[Sz - 1] := '''';
if i < List.Count - 1 then
CopyMemory(@Result[Sz], @sLineBreak[1], Length(sLineBreak) * SizeOf(Char));
Inc(Sz, 6);
end;
end;
...
begin
frxReport.Variables.Variables['Var1'] := BuildStringLiteral(s);
end;

Это работает огромное спасибо. Т. е. я так понял String вводимый из Memo который может содержать спец символы необходимо прогонять через эту функцию. Еще раз спасибо. Всем удачи но два дня потеряных жалко. Весь мозг взорвал себе. Всем удачи
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956457
SDima55
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
_Den_Z_,

Спасибо большое. Удачи. Я так понял функцию нужно делать глобальную. Пригодиться.
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956458
_Den_Z_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SDima55,

Просто все Report.Variables вычисляются как скрипт, т.е. там может быть вызов функции такой как Format или любой другой.
Соответственно все значения должны быть в виде литералов скрипта, т.е. для паскаля: 11, 1.34, '123', '123'#13#10'123' (фактически как вы пишете строковый литерал в самой Delphi).

Если вычисления выражений не нужны, то лучше использовать переменные скрипта или событие onGetValue.
А функция просто формирует строковый литерал для паскаля ('123'#13#10'123').
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956462
SDima55
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
_Den_Z_,

Решить та поставленую задачу можно было но я посчитал сто через GetValue будет не совсем правильно. Но в целом я все понял. Еще огромное спасибо. Просто интересно в инете не наше по этой теме ничего или все такие умные или у некого такого небыло.
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956465
SDima55
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SDima55,
Да еще вопрос я на другом форуме тоже задавал его. Но за день не ответил никто можно _Den_Z_ твой ответ вставить?
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956473
_Den_Z_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SDima55,
Конечно, без проблем.
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956479
_Den_Z_,

Какой ужасный код, с точки оптимизации - которую вы пытались сделать


TestBuild: 0.717718
BuildStringLiteral: 3.569232

Будь проще

Код: pascal
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.
function TestBuild(Lines: TStrings): string;
const
  SizeAlloc = 32 * 4;
var
  i, Len, current, c: Cardinal;
  wd: string;
begin
  i := Lines.Count;
  if i = 0 then
    Exit('''' + '''');

  Len := SizeAlloc;
  SetLength(Result, Len);

  wd := '''' + Lines[0] + '''';
  current := Length(wd);
  Move(wd[1], Result[1], current * SizeOf(Char));

  for i := 1 to i - 1 do
  begin
    wd := '#13#10' + '''' + Lines[i] + '''';

    c := Length(wd);

    if (current + c) > Len then
    begin
      Inc(Len, SizeAlloc);
      SetLength(Result, Len);
    end;

    Move(wd[1], Result[current], c * SizeOf(Char));
    Inc(current, c);
  end;
  SetLength(Result, current - 1);
end;




Код: pascal
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.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    Memo2: TMemo;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

var
  T, T1, T3: Int64;
  i, A: integer;

function sprintf(S: PAnsiChar; const Format: PAnsiChar): integer; cdecl; varargs; external 'msvcrt.dll';

function PrintTime(T: Int64): AnsiString;
var
  A, b: Int64;
begin
  Result := '';
  if QueryPerformanceCounter(A) and QueryPerformanceFrequency(b) then
  begin
    SetLength(Result, 25);
    SetLength(Result, sprintf(PAnsiChar(Result), '%f', single((A - T) / b)));
  end;
end;

function BuildStringLiteral(List: TStrings): String;
const
  sLineBreak = '#13#10';
var
  i, Sz, Len: integer;
begin
  if List.Count = 0 then
  begin
    Result := '''' + '''';
    Exit;
  end;
  Sz := 0;
  for i := 0 to List.Count - 1 do
    Inc(Sz, Length(List[i]) + 8);
  Dec(Sz, 6);
  SetLength(Result, Sz);
  Sz := 1;
  for i := 0 to List.Count - 1 do
  begin
    Result[Sz] := '''';
    Len := Length(List[i]);
    CopyMemory(@Result[Sz + 1], @List[i][1], Len * SizeOf(Char));
    Inc(Sz, Len + 2);
    Result[Sz - 1] := '''';
    if i < List.Count - 1 then
      CopyMemory(@Result[Sz], @sLineBreak[1], Length(sLineBreak) * SizeOf(Char));
    Inc(Sz, 6);
  end;
end;

function TestBuildStringLiteral(List: TStrings): AnsiString;
var
  arr: Pointer;
  i, r: integer;
begin
  QueryPerformanceCounter(T1);
  for r := 0 to 3 do
    for i := 0 to 1000 do
      BuildStringLiteral(List);

  Result := PrintTime(T1);
end;

function TestBuild(Lines: TStrings): string;
const
  SizeAlloc = 32 * 4;
var
  i, Len, current, c: Cardinal;
  wd: string;
begin
  i := Lines.Count;
  if i = 0 then
    Exit('''' + '''');

  Len := SizeAlloc;
  SetLength(Result, Len);

  wd := '''' + Lines[0] + '''';
  current := Length(wd);
  Move(wd[1], Result[1], current * SizeOf(Char));

  for i := 1 to i - 1 do
  begin
    wd := '#13#10' + '''' + Lines[i] + '''';

    c := Length(wd);

    if (current + c) > Len then
    begin
      Inc(Len, SizeAlloc);
      SetLength(Result, Len);
    end;

    Move(wd[1], Result[current], c * SizeOf(Char));
    Inc(current, c);
  end;
  SetLength(Result, current - 1);
end;

function TestTestBuild(List: TStrings): AnsiString;
var
  arr: Pointer;
  i, r: integer;
begin
  QueryPerformanceCounter(T1);
  for r := 0 to 3 do
    for i := 0 to 1000 do
      TestBuild(List);

  Result := PrintTime(T1);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Memo2.Lines.Add('TestBuild: ' + TestTestBuild(Memo1.Lines));
  Memo2.Lines.Add('BuildStringLiteral: ' + TestBuildStringLiteral(Memo1.Lines));
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  ShowMessage(TestBuild(Memo1.Lines));
  ShowMessage(BuildStringLiteral(Memo1.Lines));
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  i: integer;
  S: string;
begin
  S := '';
  for i := 0 to 100 do
    S := S + 'Ijisjergije488reujiorjt' + i.ToString + #13#10;
  Memo1.Text := S;
end;

end.

...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956482
SDima55
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ВсеРазумный,

Это тоже интересно т. к. отчет формируется достаточно долго много картинок но кроме него некто не от ветил поэтому ему большое спасибо а Вам спасибо
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956483
ъъъъъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Няшик, ты снова напился. Это не PHP, это FastReport.
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956485
SDima55,

Функция быстрее в 5 раз. Но в принципе можно и быстрее её сделать. Но это самый простой вариант который можно написать за 2 минуты
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956487
ъъъъъ,

Не няшик Я. И я владею 8 языками на среднем уровне. Достаточно опыта во многих сферах. Но в принципе основное - swift
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956489
SDima55
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ВсеРазумный,
Выдает Memo19 Error in expression "1#13#10'2'#13#10'3'...
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956491
SDima55,

Возможно ты где - то допустил ошибку у себя в коде, проверил, результаты одинаковые
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956493
SDima55
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SDima55,
Не я считаю что нам одним местом ***й меряься для это и существуют эти форуму. Всегда интересно но во всяком случае для меня, если есть алгоритм более быстродейсный разные задачи бывают и разные требования. Я 20 лет веду проект и раз в пять лет его переписываю по тихоньку и каждый раз думаю какой ур**д его писал. Но ВсеРазумный не заработал спервого раза буду разбираться.
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956494
SDima55
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ВсеРазумный,

Дело в том что ты в примере добавляешь одну строку а я несколько. На пустом memo у меня тоже рпаботает или с одной строкой
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956497
SDima55,

Нет, я добавляю множество строк. Приведите пример некорректной работы
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956505
SDima55
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SDima55,
Ну я тоже ввожу в своем мемо:
1
2
3
4
И выдает ошибку. Завтра посмотрю. Разберусь в чем проблема просто сейча 1 00 а я с этими апострофами вымучился два дня пытался понять что не так.
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956507
Поправка

Код: pascal
1.
current := Length(wd) + 1;





Код: pascal
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.
function TestBuild(Lines: TStrings): string;
const
  SizeAlloc = 32 * 4;
var
  i, Len, current, c: Cardinal;
  wd: string;
begin
  i := Lines.Count;
  if i = 0 then
    Exit('''' + '''');

  Len := SizeAlloc;
  SetLength(Result, Len);

  wd := '''' + Lines[0] + '''';
  current := Length(wd) + 1;
  Move(wd[1], Result[1], current * SizeOf(Char));

  for i := 1 to i - 1 do
  begin
    wd := '#13#10' + '''' + Lines[i] + '''';

    c := Length(wd);

    if (current + c) > Len then
    begin
      Inc(Len, SizeAlloc);
      SetLength(Result, Len);
    end;

    Move(wd[1], Result[current], c * SizeOf(Char));
    Inc(current, c);
  end;
  SetLength(Result, current - 1);
end;




+

...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956510
SDima55
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SDima55,

А Делфи какая?
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956511
SDima55,

Да я просто потом стёр + 1 думая что он там лишний, а на деле оказался не лишний.
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956515
Vlad F
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Походу наконец-то нашли себя. Два одиночества.))
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956516
SDima55
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SDima55,
Все ОК. Работает. Единственно время не проверял. Верю наслово. Но зделаю 2 фун-и. :)
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956517
SDima55
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Vlad F,

Когда два дня паришься с элементарной проблемой а дело все в том что не хватает знания работы с этим компонентом. Но всем огромное спасибо. Решил Оставить две функции на один отчет поцеплю одну на другой другую. Протестю на пользователях они иногда такое вытворяют.
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956527
SDima55,

Вот мой тестовый проект. Подправил его, выделив 1 функцию под тест
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
function CallList(c: TCallList; List: TStrings): AnsiString;
var
  arr: Pointer;
  i, r: integer;
begin
  QueryPerformanceCounter(T1);
  for r := 0 to 3 do
    for i := 0 to 1000 do
      c(List);

  Result := PrintTime(T1);
end;



Результаты
TestBuild: 0.734430
BuildStringLiteral: 3.627956


Код: pascal
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.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    Memo2: TMemo;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

type
  TCallList = function(List: TStrings): String;

var
  T, T1, T3: Int64;

function sprintf(S: PAnsiChar; const Format: PAnsiChar): integer; cdecl; varargs; external 'msvcrt.dll';

function PrintTime(T: Int64): AnsiString;
var
  A, b: Int64;
begin
  Result := '';
  if QueryPerformanceCounter(A) and QueryPerformanceFrequency(b) then
  begin
    SetLength(Result, 25);
    SetLength(Result, sprintf(PAnsiChar(Result), '%f', single((A - T) / b)));
  end;
end;

function BuildStringLiteral(List: TStrings): String;
const
  sLineBreak = '#13#10';
var
  i, Sz, Len: integer;
begin
  if List.Count = 0 then
  begin
    Result := '''' + '''';
    Exit;
  end;
  Sz := 0;
  for i := 0 to List.Count - 1 do
    Inc(Sz, Length(List[i]) + 8);
  Dec(Sz, 6);
  SetLength(Result, Sz);
  Sz := 1;
  for i := 0 to List.Count - 1 do
  begin
    Result[Sz] := '''';
    Len := Length(List[i]);
    CopyMemory(@Result[Sz + 1], @List[i][1], Len * SizeOf(Char));
    Inc(Sz, Len + 2);
    Result[Sz - 1] := '''';
    if i < List.Count - 1 then
      CopyMemory(@Result[Sz], @sLineBreak[1], Length(sLineBreak) * SizeOf(Char));
    Inc(Sz, 6);
  end;
end;

function TestBuild(Lines: TStrings): string;
const
  SizeAlloc = 32 * 4;
var
  i, Len, current, c: Cardinal;
  wd: string;
begin
  i := Lines.Count;
  if i = 0 then
    Exit('''' + '''');

  Len := SizeAlloc;
  SetLength(Result, Len);

  wd := '''' + Lines[0] + '''';
  current := Length(wd) + 1;
  Move(wd[1], Result[1], current * SizeOf(Char));

  for i := 1 to i - 1 do
  begin
    wd := '#13#10' + '''' + Lines[i] + '''';

    c := Length(wd);

    if (current + c) > Len then
    begin
      Inc(Len, SizeAlloc);
      SetLength(Result, Len);
    end;

    Move(wd[1], Result[current], c * SizeOf(Char));
    Inc(current, c);
  end;
  SetLength(Result, current - 1);
end;

function CallList(c: TCallList; List: TStrings): AnsiString;
var
  arr: Pointer;
  i, r: integer;
begin
  QueryPerformanceCounter(T1);
  for r := 0 to 3 do
    for i := 0 to 1000 do
      c(List);

  Result := PrintTime(T1);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Memo2.Lines.Add('TestBuild: ' + CallList(TestBuild, Memo1.Lines));
  Memo2.Lines.Add('BuildStringLiteral: ' + CallList(BuildStringLiteral, Memo1.Lines));
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  ShowMessage(TestBuild(Memo1.Lines));
  ShowMessage(BuildStringLiteral(Memo1.Lines));
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  i: integer;
  S: string;
begin
  S := '';
  for i := 0 to 100 do
    S := S + 'Ijisjergije488reujiorjt' + i.ToString + #13#10;
  Memo1.Text := S;
end;

end.

...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956528
А если сделаем 5000 строк

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
procedure TForm1.FormCreate(Sender: TObject);
var
  i: integer;
  S: string;
begin
  S := '';
  for i := 0 to 5000 do
    S := S + 'Ijisjergije488reujiorjt' + i.ToString + #13#10;
  Memo1.Text := S;
end;



Но в тесте укажем 100 раз по 3 раза
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
function CallList(c: TCallList; List: TStrings): AnsiString;
var
  arr: Pointer;
  i, r: integer;
begin
  QueryPerformanceCounter(T1);
  for r := 0 to 3 do
    for i := 0 to 100 do
      c(List);

  Result := PrintTime(T1);
end;




То результаты такие
TestBuild: 4.014073
BuildStringLiteral: 18.751520
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956531
_Den_Z_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ох уж эти оптимизаторы.

ВсеРазумный, Вам как все разумному предлагаю найти ошибку у себя в коде и объяснить, почему выделения памяти один раз (в моем варианте), медленнее чем несколько релоков в вашем. Не логично, не находите ?
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956533
SDima55
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
_Den_Z_,
Главное задача решена. Интересный форум получился. Я завтра каждый алгоритм подробней разберу сегодня тупо скопировал. :)
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956547
_Den_Z_,

Вы не знали что - ли, что память выделяется блочно. И нет смысла никакого выделять её 1 раз.

У вас слишком много времени тратиться на Length всех строк, и несколько вызовов функций.

По этому моя функция в 5 раз быстрее.
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956548
По простому. Выделив блочно 128 байт, 5 раз. Будет по скорости аналогично выделив сразу 640 байт 1 раз.
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956552
SDima55
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ВсеРазумный,
Я всегда думал что один лучше чем пять. Ну в смысле когда уже по старше стал. :)
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956553
_Den_Z_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ВсеРазумный,

Ясно, вы не знаете даже почему ваш код работает быстрей.
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956554
SDima55
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ВсеРазумный,

Это просто шутка. Ни кого не хотел обидеть.
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956555
SDima55,

Я даже не рассматривал одноразовое выделение памяти - как преимущество. Потому что в любом случае будет затрачено одно и тоже время, на выделения. (Не считая call на саму функцию)

По этому самый главный критерий который приходит на ум оптимизации, выкинуть Length всех строк, и уменьшить вызовов копирования памяти
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956556
_Den_Z_,

Я уже сказал почему мой код работает быстрее. Если вы не понимаете, почему ваш код работает так медленно, мне вас жаль. Учитесь.
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956557
_Den_Z_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ВсеРазумный,

Спасибо, буду учиться.
Только не у вас ;)
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956561
SDima55
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ВсеРазумный,

Завтра обязательно проверю. Но то что вижу CopyMemory это прослойка Move но я не думаю что это в 5 раз могло ускорить или за тормозить. Хотя Delphi это еще тот фрукт.
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956563
Ну вот, провёл тест. Сделал ещё 1 функцию копию. Но сделал фиксировано длину 5000 символов, это именно та длина, которая генерируется при

Код: pascal
1.
2.
  for i := 0 to 100 do
    S := S + 'Ijisjergije488reujiorjt' + i.ToString + #13#10;



По этому сейчас 1 место под выделения памяти

TestBuild: 0.738177
TestBuild5000Bytes: 0.729484
BuildStringLiteral: 3.590787

Разница составляет в пук младенца - 0.008693 и то, потому что я убрал
Код: pascal
1.
 if (current + c) > Len then



Код: pascal
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.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    Memo2: TMemo;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

type
  TCallList = function(List: TStrings): String;

var
  T, T1, T3: Int64;

function sprintf(S: PAnsiChar; const Format: PAnsiChar): integer; cdecl; varargs; external 'msvcrt.dll';

function PrintTime(T: Int64): AnsiString;
var
  A, b: Int64;
begin
  Result := '';
  if QueryPerformanceCounter(A) and QueryPerformanceFrequency(b) then
  begin
    SetLength(Result, 25);
    SetLength(Result, sprintf(PAnsiChar(Result), '%f', single((A - T) / b)));
  end;
end;

function BuildStringLiteral(List: TStrings): String;
const
  sLineBreak = '#13#10';
var
  i, Sz, Len: integer;
begin
  if List.Count = 0 then
  begin
    Result := '''' + '''';
    Exit;
  end;
  Sz := 0;
  for i := 0 to List.Count - 1 do
    Inc(Sz, Length(List[i]) + 8);
  Dec(Sz, 6);
  SetLength(Result, Sz);
  Sz := 1;
  for i := 0 to List.Count - 1 do
  begin
    Result[Sz] := '''';
    Len := Length(List[i]);
    CopyMemory(@Result[Sz + 1], @List[i][1], Len * SizeOf(Char));
    Inc(Sz, Len + 2);
    Result[Sz - 1] := '''';
    if i < List.Count - 1 then
      CopyMemory(@Result[Sz], @sLineBreak[1], Length(sLineBreak) * SizeOf(Char));
    Inc(Sz, 6);
  end;
end;

function TestBuild(Lines: TStrings): string;
const
  SizeAlloc = 32 * 4;
var
  i, Len, current, c: Cardinal;
  wd: string;
begin
  i := Lines.Count;
  if i = 0 then
    Exit('''' + '''');

  Len := SizeAlloc;
  SetLength(Result, Len);

  wd := '''' + Lines[0] + '''';
  current := Length(wd) + 1;
  Move(wd[1], Result[1], current * SizeOf(Char));

  for i := 1 to i - 1 do
  begin
    wd := '#13#10' + '''' + Lines[i] + '''';

    c := Length(wd);

    if (current + c) > Len then
    begin
      Inc(Len, SizeAlloc);
      SetLength(Result, Len);
    end;

    Move(wd[1], Result[current], c * SizeOf(Char));
    Inc(current, c);
  end;
  SetLength(Result, current - 1);
end;

function TestBuild5000Bytes(Lines: TStrings): string;
const
  SizeAlloc = 5000;
var
  i, Len, current, c: Cardinal;
  wd: string;
begin
  i := Lines.Count;
  if i = 0 then
    Exit('''' + '''');

  Len := SizeAlloc;
  SetLength(Result, Len);

  wd := '''' + Lines[0] + '''';
  current := Length(wd) + 1;
  Move(wd[1], Result[1], current * SizeOf(Char));

  for i := 1 to i - 1 do
  begin
    wd := '#13#10' + '''' + Lines[i] + '''';

    c := Length(wd);

    // if (current + c) > Len then
    begin
      // Inc(Len, SizeAlloc);
      // SetLength(Result, Len);
    end;

    Move(wd[1], Result[current], c * SizeOf(Char));
    Inc(current, c);
  end;
  SetLength(Result, current - 1);
end;

function CallList(c: TCallList; List: TStrings): AnsiString;
var
  arr: Pointer;
  i, r: integer;
begin
  QueryPerformanceCounter(T1);
  for r := 0 to 3 do
    for i := 0 to 1000 do
      c(List);

  Result := PrintTime(T1);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Memo2.Lines.Add('TestBuild: ' + CallList(TestBuild, Memo1.Lines));
  Memo2.Lines.Add('TestBuild5000Bytes: ' + CallList(TestBuild5000Bytes, Memo1.Lines));
  Memo2.Lines.Add('BuildStringLiteral: ' + CallList(BuildStringLiteral, Memo1.Lines));
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  ShowMessage(TestBuild(Memo1.Lines));
  ShowMessage(BuildStringLiteral(Memo1.Lines));
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  i: integer;
  S: string;
begin
  S := '';
  for i := 0 to 100 do
    S := S + 'Ijisjergije488reujiorjt' + i.ToString + #13#10;
  Memo1.Text := S;
end;

end.

...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956564
_Den_Z_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ВсеРазумный,

Даю подсказку, Memo.Lines это не TStringList.
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956565
SDima55
ВсеРазумный,

Завтра обязательно проверю. Но то что вижу CopyMemory это прослойка Move но я не думаю что это в 5 раз могло ускорить или за тормозить. Хотя Delphi это еще тот фрукт.


Не надо мифов. Эта inline функция
Код: sql
1.
006027F7 E84448E0FF       call Move





Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
Unit1.pas.72: CopyMemory(@Result[Sz + 1], @List[i][1], Len * SizeOf(Char));
006027C2 8B45F8           mov eax,[ebp-$08]
006027C5 E8467AE0FF       call @UniqueStringU
006027CA 8B55F0           mov edx,[ebp-$10]
006027CD 8D0450           lea eax,[eax+edx*2]
006027D0 8945D4           mov [ebp-$2c],eax
006027D3 8D4DC0           lea ecx,[ebp-$40]
006027D6 8B55F4           mov edx,[ebp-$0c]
006027D9 8B45FC           mov eax,[ebp-$04]
006027DC 8B18             mov ebx,[eax]
006027DE FF530C           call dword ptr [ebx+$0c]
006027E1 8B45C0           mov eax,[ebp-$40]
006027E4 E86380E0FF       call @UStrToPWChar
006027E9 8945D0           mov [ebp-$30],eax
006027EC 8B4DEC           mov ecx,[ebp-$14]
006027EF 03C9             add ecx,ecx
006027F1 8B55D4           mov edx,[ebp-$2c]
006027F4 8B45D0           mov eax,[ebp-$30]
006027F7 E84448E0FF       call Move

...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956567
_Den_Z_
ВсеРазумный,

Даю подсказку, Memo.Lines это не TStringList.


Ой пасибо

Код: pascal
1.
  TStringList = class(TStrings)



А мы и не знали, и не умели делать TStrings AS TStringList
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956569
_Den_Z_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ВсеРазумный,
Надеюсь, что вы троллите иначе конечно, это печально.
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956571
SDima55
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ВсеРазумный,

Код: pascal
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.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
procedure CopyMemory(Destination: Pointer; Source: Pointer; Length: DWORD);
begin
  Move(Source^, Destination^, Length);
end;

а

(* ***** BEGIN LICENSE BLOCK *****
 *
 * The assembly function Move is licensed under the CodeGear license terms.
 *
 * The initial developer of the original code is Fastcode
 *
 * Portions created by the initial developer are Copyright (C) 2002-2004
 * the initial developer. All Rights Reserved.
 *
 * Contributor(s): John O'Harrow
 *
 * ***** END LICENSE BLOCK ***** *)
procedure Move(const Source; var Dest; count : Integer);
{$IFDEF PUREPASCAL}
var
  S, D: PAnsiChar;
  I: Integer;
begin
  S := PAnsiChar(@Source);
  D := PAnsiChar(@Dest);
  if S = D then Exit;
  if Cardinal(D) > Cardinal(S) then
    for I := count-1 downto 0 do
      D[I] := S[I]
  else
    for I := 0 to count-1 do
      D[I] := S[I];
end;
{$ELSE}
asm
  cmp     eax, edx
  je      @@Exit {Source = Dest}
  cmp     ecx, 32
  ja      @@LargeMove {Count > 32 or Count < 0}
  sub     ecx, 8
  jg      @@SmallMove
@@TinyMove: {0..8 Byte Move}
  jmp     dword ptr [@@JumpTable+32+ecx*4]
@@SmallMove: {9..32 Byte Move}
  fild    qword ptr [eax+ecx] {Load Last 8}
  fild    qword ptr [eax] {Load First 8}
  cmp     ecx, 8
  jle     @@Small16
  fild    qword ptr [eax+8] {Load Second 8}
  cmp     ecx, 16
  jle     @@Small24
  fild    qword ptr [eax+16] {Load Third 8}
  fistp   qword ptr [edx+16] {Save Third 8}
@@Small24:
  fistp   qword ptr [edx+8] {Save Second 8}
@@Small16:
  fistp   qword ptr [edx] {Save First 8}
  fistp   qword ptr [edx+ecx] {Save Last 8}
@@Exit:
  ret
  nop {4-Byte Align JumpTable}
  nop
@@JumpTable: {4-Byte Aligned}
  dd      @@Exit, @@M01, @@M02, @@M03, @@M04, @@M05, @@M06, @@M07, @@M08
@@LargeForwardMove: {4-Byte Aligned}
  push    edx
  fild    qword ptr [eax] {First 8}
  lea     eax, [eax+ecx-8]
  lea     ecx, [ecx+edx-8]
  fild    qword ptr [eax] {Last 8}
  push    ecx
  neg     ecx
  and     edx, -8 {8-Byte Align Writes}
  lea     ecx, [ecx+edx+8]
  pop     edx
@FwdLoop:
  fild    qword ptr [eax+ecx]
  fistp   qword ptr [edx+ecx]
  add     ecx, 8
  jl      @FwdLoop
  fistp   qword ptr [edx] {Last 8}
  pop     edx
  fistp   qword ptr [edx] {First 8}
  ret
@@LargeMove:
  jng     @@LargeDone {Count < 0}
  cmp     eax, edx
  ja      @@LargeForwardMove
  sub     edx, ecx
  cmp     eax, edx
  lea     edx, [edx+ecx]
  jna     @@LargeForwardMove
  sub     ecx, 8 {Backward Move}
  push    ecx
  fild    qword ptr [eax+ecx] {Last 8}
  fild    qword ptr [eax] {First 8}
  add     ecx, edx
  and     ecx, -8 {8-Byte Align Writes}
  sub     ecx, edx
@BwdLoop:
  fild    qword ptr [eax+ecx]
  fistp   qword ptr [edx+ecx]
  sub     ecx, 8
  jg      @BwdLoop
  pop     ecx
  fistp   qword ptr [edx] {First 8}
  fistp   qword ptr [edx+ecx] {Last 8}
@@LargeDone:
  ret
@@M01:
  movzx   ecx, [eax]
  mov     [edx], cl
  ret
@@M02:
  movzx   ecx, word ptr [eax]
  mov     [edx], cx
  ret
@@M03:
  mov     cx, [eax]
  mov     al, [eax+2]
  mov     [edx], cx
  mov     [edx+2], al
  ret
@@M04:
  mov     ecx, [eax]
  mov     [edx], ecx
  ret
@@M05:
  mov     ecx, [eax]
  mov     al, [eax+4]
  mov     [edx], ecx
  mov     [edx+4], al
  ret
@@M06:
  mov     ecx, [eax]
  mov     ax, [eax+4]
  mov     [edx], ecx
  mov     [edx+4], ax
  ret
@@M07:
  mov     ecx, [eax]
  mov     eax, [eax+3]
  mov     [edx], ecx
  mov     [edx+3], eax
  ret
@@M08:
  fild    qword ptr [eax]
  fistp   qword ptr [edx]
end; 
{$ENDIF}



Модератор: Пользуйтесь тегом (кнопкой) SRC для оформления кода, пожалуйста.
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956572
SDima55
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
_Den_Z_,

Я обязательно завтра проверю. Раз пошла такая пьянка.
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956573
_Den_Z_
ВсеРазумный,
Надеюсь, что вы троллите иначе конечно, это печально.


Это вы издеваетесь, честное слово.

Код: pascal
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.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    Memo2: TMemo;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

var
  T, T1, T3: Int64;
  i, A: integer;

function sprintf(S: PAnsiChar; const Format: PAnsiChar): integer; cdecl; varargs; external 'msvcrt.dll';

function PrintTime(T: Int64): AnsiString;
var
  A, b: Int64;
begin
  Result := '';
  if QueryPerformanceCounter(A) and QueryPerformanceFrequency(b) then
  begin
    SetLength(Result, 25);
    SetLength(Result, sprintf(PAnsiChar(Result), '%f', single((A - T) / b)));
  end;
end;

function BuildStringLiteral(List: TStrings): String;
const
  sLineBreak = '#13#10';
var
  i, Sz, Len: integer;
begin
  if List.Count = 0 then
  begin
    Result := '''' + '''';
    Exit;
  end;
  Sz := 0;
  for i := 0 to List.Count - 1 do
    Inc(Sz, Length(List[i]) + 8);
  Dec(Sz, 6);
  SetLength(Result, Sz);
  Sz := 1;
  for i := 0 to List.Count - 1 do
  begin
    Result[Sz] := '''';
    Len := Length(List[i]);
    CopyMemory(@Result[Sz + 1], @List[i][1], Len * SizeOf(Char));
    Inc(Sz, Len + 2);
    Result[Sz - 1] := '''';
    if i < List.Count - 1 then
      CopyMemory(@Result[Sz], @sLineBreak[1], Length(sLineBreak) * SizeOf(Char));
    Inc(Sz, 6);
  end;
end;

function TestBuildStringLiteral(List: TStrings): AnsiString;
var
  arr: Pointer;
  i, r: integer;
begin
  QueryPerformanceCounter(T1);
  for r := 0 to 3 do
    for i := 0 to 1000 do
      BuildStringLiteral(List);

  Result := PrintTime(T1);
end;

function TestBuild(Lines: TStringList): string;
const
  SizeAlloc = 32 * 4;
var
  i, Len, current, c: Cardinal;
  wd: string;
begin
  i := Lines.Count;
  if i = 0 then
    Exit('''' + '''');

  Len := SizeAlloc;
  SetLength(Result, Len);

  wd := '''' + Lines[0] + '''';
  current := Length(wd) + 1;
  Move(wd[1], Result[1], current * SizeOf(Char));

  for i := 1 to i - 1 do
  begin
    wd := '#13#10' + '''' + Lines[i] + '''';

    c := Length(wd);

    if (current + c) > Len then
    begin
      Inc(Len, SizeAlloc);
      SetLength(Result, Len);
    end;

    Move(wd[1], Result[current], c * SizeOf(Char));
    Inc(current, c);
  end;
  SetLength(Result, current - 1);
end;

function TestTestBuild(List: TStringList): AnsiString;
var
  arr: Pointer;
  i, r: integer;
begin
  QueryPerformanceCounter(T1);
  for r := 0 to 3 do
    for i := 0 to 1000 do
      TestBuild(List);

  Result := PrintTime(T1);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Memo2.Lines.Add('TestBuild: ' + TestTestBuild(TStringList(Memo1.Lines)));
  Memo2.Lines.Add('BuildStringLiteral: ' + TestBuildStringLiteral(Memo1.Lines));
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  ShowMessage(TestBuild(TStringList(Memo1.Lines)));
  ShowMessage(BuildStringLiteral(Memo1.Lines));
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  i: integer;
  S: string;
begin
  S := '';
  for i := 0 to 100 do
    S := S + 'Ijisjergije488reujiorjt' + i.ToString + #13#10;
  Memo1.Text := S;
end;

end.



Заменив TStrings на TStringList ничего не поменялось.

TestBuild: 0.730820
BuildStringLiteral: 3.607540


К чему вы вообще начали этот пустой разговор?
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956575
SDima55,

Кстати, в компиляторе большое количество функций компилируется как inline но вы не увидите рядом с функцией слово inline так как это задаётся внутри компилятора

К примеру FreeAndNil тоже inline функция хоть на ней это не написано. Но в скомпилированном коде к ней нет вызова, идёт встраивания
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956577
_Den_Z_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SDima55,

Если вы действительно используете TStringList, а не прямой доступ к Memo.Lines , то разницы почти не будет.
Вообще Memo.Lines лучше на прямую не использовать в передаче и обработке текста, особенно если понадобится вынести работу с отчетом в потоки. Memo.Lines является экземпляром TMemoStrings , который работает через sendMessage на каждый Lines[i] вызов Get c sendMessage .
Отсюда и задержка такая в моем варианте. Если как вы и описали, к вас TStringList то изначальный вариант будет быстрей, правда не значительно.
ВсеРазумный , к сожалению не до конца понимает о чем говорит, не разобравшись ни в описании проблемы, ни почему его вариант "быстрей".
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956578
_Den_Z_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ВсеРазумный

Это вы издеваетесь, честное слово.


Жесть, кастовать класс TMemoStrings к TStringList.
Продолжайте, я заинтрегован.
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956583
Ясно. Незнание ООП и простейшей Иерархии обращений к предкам.

Понятно, что если мы будем работать с чистым string быстрее. Но я хотел привести пример, что ваш код - с точки зрения в изначальном проектирование - фуфло.

Не потому что вы используете TString с sendMessage А потому что вы нагородили огород с огурцами, помидорами и картошкой.


Вы мистер КЭП. И быстрее ваш код, моей функции не будет. Так как я уже сказал: проектирование функции - фуфло

1) Вы делается цикл по всем строкам, и считаете длину
Код: pascal
1.
2.
 for i := 0 to List.Count - 1 do
     Inc(Sz, Length(List[i]) + 8);



Слишком много хлама дальше. Это именно - то, почему ваша функция медленная.
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956587
ВсеРазумный
Понятно, что если мы будем работать с чистым string быстрее


Код: pascal
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.
function TStrings.GetTextStr: string;
var
  I, L, Size, Count: Integer;
  P: PChar;
  S, LB: string;
begin
  Count := GetCount;
  Size := 0;
  LB := LineBreak;
  for I := 0 to Count - 1 do Inc(Size, Length(Get(I)) + Length(LB));
  if not TrailingLineBreak then
    Dec(Size, Length(LB));
  SetString(Result, nil, Size);
  P := Pointer(Result);
  for I := 0 to Count - 1 do
  begin
    S := Get(I);
    L := Length(S);
    if L <> 0 then
    begin
      System.Move(Pointer(S)^, P^, L * SizeOf(Char));
      Inc(P, L);
    end;
    if TrailingLineBreak or (I < Count - 1) then
    begin
      L := Length(LB);
      if L <> 0 then
      begin
        System.Move(Pointer(LB)^, P^, L * SizeOf(Char));
        Inc(P, L);
      end;
    end;
  end;
end;




Нее.. Не будет, к сожалению. Все варианты ведут на эту функцию.

Быстрее, избавится вообще от TMemo
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956588
ъъъъъ,

Всё уже ясно. Моя функция - лучший вариант. И быстрее уже не написать. Если только избавится от TMemo в принципе.

Так как вообще всё TStrings\TStringList использует одну функцию - GetTextStr
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956589
Если вы сидите и думаете что один вызов setlength будет быстрее чем пару выделений по 128 но при этом используете

Код: pascal
1.
2.
  for i := 0 to List.Count - 1 do
    Inc(Sz, Length(List[i]) + 8);



То это Полная беда.. И тут лечится уже надо.
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956590
_Den_Z_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ВсеРазумный,

Мда, интересно посмотреть в какой это версии Delphi TMemoStrings от TStringList.
В прочем, уже не важно, с вами уже все понятно. Неприятно правда, что вы вводите людей в заблуждение, но это уже на совести конкретного человека кто принимает решение, я дал человеку максимальное объяснение происходящего.

А тут наверное, делфа заглючила. Что-то быстрей стало исполнятся
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956592
_Den_Z_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ну и ваш же пример.
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956594
_Den_Z_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Можете попробовать оптимизировать еще через ассемблерные вставки, чем черт не шутит
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956616
white_nigger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Den_Z_, не парься. Здесь хватает "оптимизаторов от Бога"))
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956847
_Den_Z_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
white_nigger,
Я с саппортом периодически работаю, после этого мало что может удивить )
Но топик наткнул на идею, добавить в список вопросов на собеседование, примерно такой :


Дана функция которая работает со строкой:

Код: pascal
1.
2.
3.
4.
procedure DoSomethingWithString(str: PChar; Len: Integer);
begin
 //работа с str
end;




Есть ли принципиальное отличие в приведенных ниже вызовах функций ?
Какая из них будет работать быстрее и почему ?

Вариант 1:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
procedure DoSomething;
var
  i, Len: integer;
  S: string;
begin
  S := 'Строка длинной 1000 символов.';
  Len := Length(s);
  for i := 0 to 1000 do
    DoSomethingWithString(PChar(@S[1]), Len);
end;



Вариант 2:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
procedure DoSomething;
var
  i: integer;
  S: string;
begin
  S := 'Строка длинной 1000 символов.';
  for i := 0 to 1000 do
    DoSomethingWithString(PChar(@S[1]), Length(s));
end;



Извините за оффтоп.
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956873
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Den_Z_
добавить в список вопросов на собеседование

Рановато в собеседники идти.
_Den_Z_
Код: pascal
1.
2.
  S := 'Строка длинной 1000 символов.';
  for i := 0 to 1000 do


Даже не смотря на PChar(@S[1]) и бессмысленность примера в целом.

Разве что избавиться от конкуренции? :)
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956880
_Den_Z_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
wadman,

Простите, а что не так ? Это , конечно, не теннисными мячиками автобус заполнять.
Или нужно писать код генерации строки длинной 1000 символов. Тут отброшены все условности , чтобы поместилось на бумажке.
Суть то вопроса, не найти смысл в коде. А выявить различия и понять играют ли они роль.
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956886
ъъъъъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
wadman
_Den_Z_
добавить в список вопросов на собеседование

Рановато в собеседники идти.
_Den_Z_
Код: pascal
1.
2.
  S := 'Строка длинной 1000 символов.';
  for i := 0 to 1000 do


...

...


Числа одинаковые? Или что?
Вирус оптимизаторства зацепил?

Код: pascal
1.
2.
3.
4.
const cOneThousand = 1000;
begin
  S := Format('Строка длинной %d символов.', [cOneThousand])
  for i := 0 to cOneThousand do


- так надо было?
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956894
_Den_Z_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ъъъъъ,
Наоборот, испугался подхватить. Это просто примерный шаблон, цикл, функцию(WINAPI, Move итд) можно заменить ,если уж так нужен смысл в этом куске кода. Просто поделился идеей, основываясь на бреде про использование Length из топика.

Упор сделан на Length, в цикле и вне цикла.
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956896
ъъъъъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
_Den_Z_,

да я понял... :)
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956897
goldmi45
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ъъъъъ,

если в строке 1000 символов, то цикл по этой строке будет от 0 до 1000-1, как бы... На это wadman намекал.
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956902
_Den_Z_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
goldmi45,
Цикл там не по строке идет, идея не в этом. Как уже написал, можно заменить цикл на что-то вменяемое, это просто идея основанная на топике :)
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956914
ъъъъъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
goldmi45
ъъъъъ,

если в строке 1000 символов, то цикл по этой строке будет от 0 до 1000-1, как бы...

С фига ли? А если в строке 5 символов - то цикл должен быть от 0 до 5-1?
Какая связь между длиной строки и циклом в примере? Никакой.
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956917
asviridenkov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Den_Z_,

Разница там меньше чем в полтора раза. И вопрос очевидный а вот более интересный вопрос, как первую функцию можно ускорить еще в полтора раза, изменив всего с десяток символов.
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956918
goldmi45
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Den_Z_
goldmi45,
Цикл там не по строке идет, идея не в этом. Как уже написал, можно заменить цикл на что-то вменяемое, это просто идея основанная на топике :)

Ok :)
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956923
goldmi45
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ъъъъъ
goldmi45
ъъъъъ,

если в строке 1000 символов, то цикл по этой строке будет от 0 до 1000-1, как бы...

С фига ли? А если в строке 5 символов - то цикл должен быть от 0 до 5-1?

Если циклом бежим по строке, длиной 5 символов, то должно быть 5 итераций цикла. Если нижняя граница 0, то верхняя 5-1. Если нижняя граница 1, то верхняя 5.
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956941
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Den_Z_
Суть то вопроса, не найти смысл в коде. А выявить различия и понять играют ли они роль.

"Представьте сферического коня в вакууме".

Если отбросить полное отсутствие логики (чёрт, а ведь программисту она нужна?), то чтобы заметить разницу нужно увеличить цикл хотя-бы до 1 млн итераций.

Зы. Разница между ними не должна быть критичной, как и сам вопрос - критерием.
...
Рейтинг: 0 / 0
Fast Report - апострофы в переменных
    #39956944
_Den_Z_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
wadman,
Да, я же написал, что это просто абстрактная идея, навеянная топиком.
Никому не хотел сломать мозг, извините :)
...
Рейтинг: 0 / 0
84 сообщений из 84, показаны все 4 страниц
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Fast Report - апострофы в переменных
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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