powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Работа с PChar
25 сообщений из 92, страница 2 из 4
Работа с PChar
    #39474113
Bred eFeM
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
defecator, а лимит какой?

Да какой там лимит, товарищь не заметил как у него ~4 гига! в памяти лишний раз прочиталось-записалось на 2 метровом файле, и к своим 50МБ он ниразу ещё и не подобрался видать.

А AV, наверно, повылазили из-за ощутимых задержек при обработке, может в GUI, может в доп потоках.
...
Рейтинг: 0 / 0
Работа с PChar
    #39474135
SOFT FOR YOU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Bred eFeM,

Я думаю AV генерируется при реаллоке если не хватает памяти. Вроде бы я ничего не путаю
...
Рейтинг: 0 / 0
Работа с PChar
    #39474139
Фотография defecator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
SOFT FOR YOUАвтору нужна запись 50Мб быстро. CachedBuffers писал 100Мб на тестах за 100мск. О чем мы говорим?
про NativeXML
...
Рейтинг: 0 / 0
Работа с PChar
    #39474140
schi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Но если бы у рыб была шерсть, то в ней бы водились блохи.
...
Рейтинг: 0 / 0
Работа с PChar
    #39474142
SOFT FOR YOU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
defecator,

Он же тормоз. Зачем про него вообще говорить? Уже если о чём-то и говорить готовом, так об OmniXML
...
Рейтинг: 0 / 0
Работа с PChar
    #39474159
Alimkulov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ура!!!
Получился, да ребята вы молодцы!
Проблема была с выделением буфера. Вот теперь летает, супер!
Вот последний рабочий вариант:
TXMLWriter
Код: 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.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
unit XMLWriter;

interface

uses
  Classes, SysUtils;

type

  TXmlStandalone = (xsOmit, xsYes, xsNo);

  TXmlCloseTag = (xtNone, xtClose, xtSlashClose);

  TXMLWriter = class
  private
    FBuffer: PChar;
    FCursor: PChar;
    FLast: PChar;
    procedure MoveCursor(Delta: Integer);
    procedure Grow;
  public
    constructor Create(const Standalone: TXmlStandalone);
    destructor Destroy; override;
    procedure WriteValue(const pValue: PChar);
    procedure OpenElement(const pName: PChar; const CloseTag: TXmlCloseTag);
    procedure WriteElement(const pName, pValue: PChar);
    procedure WriteAttribute(const pName, pValue: PChar; const CloseTag: TXmlCloseTag); overload;
    procedure WriteBuffer(const pBuffer: PChar);
    procedure WriteChar(const pValue: Char);
    procedure CloseElement(const pName: PChar);
    procedure CloseDocument;
    procedure SaveToFile(const FileName: string);
    procedure SaveToStream(const Stream: TStream);
    property Buffer: PChar read FBuffer;
  end;

implementation

uses Math, Windows;

const

  cOpenTag: Char = '<';
  cCloseTag: Char = '>';
  cSlash: Char = '/';
  cOpenSlashTag: PChar = '</';
  cSlashCloseTag: PChar = '/>';
  cSpace: Char = ' ';
  cEquality: Char = '=';
  cApostrophe: Char = '"';
  cEqualApos: PChar = '="';
  clt: PChar = '%lt;';
  cgt: PChar = '%gt;';
  cmp: PChar = '&amp;';
  cqt: PChar = '&quot;';

  cXml = '<?xml version="1.0" encoding="UTF-8" standalone="%s" ?>';
  cStandalones: array [TXmlStandalone] of string = ('omit', 'yes', 'no');

  { TXMLWriter }

constructor TXMLWriter.Create(const Standalone: TXmlStandalone);
begin
  // init mem
  FBuffer := GlobalAllocPtr(HeapAllocFlags, $100);
  FCursor := FBuffer;
  FLast := FCursor + $100;

  // xml declarations
  WriteBuffer(PChar(Format(cXml, [cStandalones[Standalone]])));
end;

destructor TXMLWriter.Destroy;
begin
  GlobalFreePtr(FBuffer);
  FCursor := nil;
  FLast := nil;
  FBuffer := nil;
  inherited Destroy;
end;


procedure TXMLWriter.OpenElement(const pName: PChar;
  const CloseTag: TXmlCloseTag);
begin
  WriteChar(cOpenTag);
  WriteBuffer(pName);
  case CloseTag of
    xtClose:
      WriteChar(cCloseTag);
    xtSlashClose:
      WriteBuffer(cSlashCloseTag);
  end;
end;

procedure TXMLWriter.CloseElement(const pName: PChar);
begin
  WriteBuffer(cOpenSlashTag);
  WriteBuffer(pName);
  WriteChar(cCloseTag);
end;

procedure TXMLWriter.WriteElement(const pName, pValue: PChar);
begin
  OpenElement(pName, xtClose);
  if pValue <> nil then
  begin
    WriteValue(pValue);
    CloseElement(pName);
  end
  else
    WriteBuffer(cSlashCloseTag);
end;

procedure TXMLWriter.WriteAttribute(const pName, pValue: PChar;
  const CloseTag: TXmlCloseTag);
begin
  WriteChar(cSpace);
  WriteBuffer(pName);
  WriteBuffer(cEqualApos);
  WriteValue(pValue);
  WriteChar(cApostrophe);
  case CloseTag of
    xtClose:
      WriteChar(cCloseTag);
    xtSlashClose:
      WriteBuffer(cSlashCloseTag);
  end;
end;

procedure TXMLWriter.WriteBuffer(const pBuffer: PChar);
var
  P: PChar;
begin
  P := pBuffer;
  while P^ <> #0 do
  begin
    FCursor^ := P^;
    MoveCursor(1);
    Inc(P);
  end;
end;

procedure TXMLWriter.WriteChar(const pValue: Char);
begin
  FCursor^ := pValue;
  MoveCursor(1);
end;

procedure TXMLWriter.WriteValue(const pValue: PChar);
var
  P: PChar;
  n: Integer;
begin
  P := pValue;
  while P^ <> #0 do
  begin
    case P^ of
      '<':
        begin
          WriteBuffer(clt);
          Inc(P);
        end;
      '>':
        begin
          WriteBuffer(cgt);
          Inc(P);
        end;
      '&':
        begin
          WriteBuffer(cmp);
          Inc(P);
        end;
      '"':
        begin
          WriteBuffer(cqt);
          Inc(P);
        end
    else
      begin
        FCursor^ := P^;
        MoveCursor(1);
        Inc(P);
      end;
    end
  end;
end;


procedure TXMLWriter.Grow;
var
  Cursor, Capacity: Integer;
begin
  Cursor := LongInt(FCursor - FBuffer);
  Capacity := LongInt(FLast - FBuffer);
  Capacity := Capacity + (Capacity div 4);
  FBuffer := GlobalReallocPtr(FBuffer, Capacity, HeapAllocFlags);
  FLast := FBuffer + Capacity;
  FCursor := FBuffer + Cursor;
end;


procedure TXMLWriter.MoveCursor(Delta: Integer);
begin
  Inc(FCursor, Delta);
  if FCursor = FLast then
    Grow
end;

procedure TXMLWriter.SaveToFile(const FileName: string);
var
  FileStream: TFileStream;
begin
  FileStream := TFileStream.Create(FileName, fmCreate);
  try
    SaveToStream(FileStream);
  finally
    FileStream.Free;
  end;
end;

procedure TXMLWriter.SaveToStream(const Stream: TStream);
var
  DataString: UTF8String;
begin
  DataString := UTF8Encode(Buffer);
  Stream.Write(DataString[1], Length(DataString));
end;

procedure TXMLWriter.CloseDocument;
var
  Cursor: Integer;
  Capacity: Integer;
begin
  if FCursor < FLast then
  begin
    Cursor := LongInt(FCursor - FBuffer);
    Capacity := (Cursor + $1FFF) and not $1FFF;
    FBuffer := GlobalReallocPtr(FBuffer, Capacity, HeapAllocFlags);
    FLast := FBuffer + Capacity;
    FCursor := FBuffer + Cursor;
  end;
  FCursor^ := #0;
end;

end.



Вы очень помогли мне!
Уважаемые профессионалы, давайте предложение о том, как можно еще ускорить формирование простого XML документа.
...
Рейтинг: 0 / 0
Работа с PChar
    #39474192
SOFT FOR YOU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alimkulov,

Я же написал )
...
Рейтинг: 0 / 0
Работа с PChar
    #39474197
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlimkulovУважаемые профессионалы, давайте предложение о том, как можно еще ускорить формирование простого XML документа.
Оптимизируй WriteBuffer.
Он у тебя по 1 байту циклы гоняет.

Сделай блочно через Move.
...
Рейтинг: 0 / 0
Работа с PChar
    #39474200
SOFT FOR YOU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alimkulov,

Я предвижу холивары. Поэтому замути тестовое приложение, в котором замеряется время. И тогда можно будет онлайн наблюдать, как то или иное решение оказывает влияние на производительность. И ещё момент. Исходные данные у тебя в какой кодировке? Ansi, Utf8 или Utf16(Wide)?
...
Рейтинг: 0 / 0
Работа с PChar
    #39474202
Alimkulov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SOFT FOR YOUAlimkulov,

Я же написал )

Да да, как раз я сейчас посмотрю CachedBuffers и CachedTexts.
...
Рейтинг: 0 / 0
Работа с PChar
    #39474204
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rgreatAlimkulovУважаемые профессионалы, давайте предложение о том, как можно еще ускорить формирование простого XML документа.
Оптимизируй WriteBuffer.
Он у тебя по 1 байту циклы гоняет.

Сделай блочно через Move.Хотя если у тебя там все элементы длиной максимум в несколько байт как в тесте - то смысла нет.
...
Рейтинг: 0 / 0
Работа с PChar
    #39474205
Няшик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Зачем вообще выделять буфер ручками ?

Установили начальную точку str := ''; и записываем дальше str := str + ''; Это очень быстро работает, и париться не надо с выделением, и копированием по одному символу! Что вообще целый ад.

Ещё можно сделать функции inline что может не хило так сэкономить времени (В ущерб весу программы. Хотя пусть весит хоть 60 Главное скорость работы, что например у Java на нищем уровне при размерах, и аппетита по памяти)
...
Рейтинг: 0 / 0
Работа с PChar
    #39474212
Фотография defecator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
НяшикЗачем вообще выделять буфер ручками ?

Установили начальную точку str := ''; и записываем дальше str := str + ''; Это очень быстро работает
конкатенация строк работает очень быстро ?
...
Рейтинг: 0 / 0
Работа с PChar
    #39474214
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НяшикУстановили начальную точку str := ''; и записываем дальше str := str + ''; Это очень быстро работает, и париться не надо с выделением, и копированием по одному символу! Что вообще целый ад. А-ха-ха!

Полное копирование всей строки при добалении в нее - быстрым быть не может.
...
Рейтинг: 0 / 0
Работа с PChar
    #39474215
schi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlimkulovМне потребовалось написать такой XML генератор, который работает очень быстро.


Я бы озвучил требования к скорости и уже на основании этих требований искал бы пути реализации. За микросекунду 5 гигабайт ты никак не сгенерируешь, например.
...
Рейтинг: 0 / 0
Работа с PChar
    #39474216
Alimkulov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НяшикЗачем вообще выделять буфер ручками ?

Установили начальную точку str := ''; и записываем дальше str := str + ''; Это очень быстро работает, и париться не надо с выделением, и копированием по одному символу! Что вообще целый ад.

В начале я тоже так думал! Но у меня str := str + '' так долго, что терпения не хватила, чтоб подождать процесса до конца!
Это из за Delphi 6 наверное.
...
Рейтинг: 0 / 0
Работа с PChar
    #39474218
Фотография defecator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
schiAlimkulovМне потребовалось написать такой XML генератор, который работает очень быстро.


Я бы озвучил требования к скорости и уже на основании этих требований искал бы пути реализации. За микросекунду 5 гигабайт ты никак не сгенерируешь , например.

Ты что ! СофтФорЮ может и быстрее !
...
Рейтинг: 0 / 0
Работа с PChar
    #39474222
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
defecatorконкатенация строк работает очень быстро ?
Довольно быстро, при наличии FastMM. Беда, когда его нет :)
...
Рейтинг: 0 / 0
Работа с PChar
    #39474227
SOFT FOR YOU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
defecator,

Пффф, гуано-вопрос )
...
Рейтинг: 0 / 0
Работа с PChar
    #39474230
Фотография defecator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
SOFT FOR YOUdefecator,

Пффф, гуано-вопрос )

Ага, такой же, как с "самым быстрым в мире менеджером памяти"
Там тоже был "говно вопрос", а получился пшик
...
Рейтинг: 0 / 0
Работа с PChar
    #39474234
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlimkulovВ начале я тоже так думал! Но у меня str := str + '' так долго, что терпения не хватила, чтоб подождать процесса до конца!
Это из за Delphi 6 наверное.
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
procedure AddStr(var Str: string; const Str2: string);
var
  n : integer;
begin
  if length(Str2)=0 then Exit;

  n:=Length(Str);
  SetLength(Str,n+length(Str2));
  Move(Str2[1],Str[n+1],Length(Str2)*SizeOf(Char));
end;
...
Рейтинг: 0 / 0
Работа с PChar
    #39474237
SOFT FOR YOU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
defecator,

Я занят рефакторингом CrystalLUA. Юникод, x64, задел под ARM/FPC, немного оптимизаций. Вы же не в состоянии программировать на уровне. Приходится делать в одиночку )
...
Рейтинг: 0 / 0
Работа с PChar
    #39474239
Alimkulov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
schi За микросекунду 5 гигабайт ты никак не сгенерируешь, например.

Test
Код: 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.
procedure TForm1.btn1Click(Sender: TObject);
var
  x : TXMLWriter;
  i, j : Integer;
  p : PChar;
  tc : Integer;
begin
  x := TXMLWriter.Create(xsYes);
  try
    tc := GetTickCount;

    x.OpenElement(c1, xtClose);
    for i := 0 to 850254 do
    begin
      x.OpenElement(c2, xtNone);
      x.WriteAttribute(c3, PChar(IntToStr(i)), xtClose);

      for j := 0 to 24 do
      begin
        x.OpenElement(c4, xtNone);
        x.WriteAttribute(c5, PChar(IntToStr(j)), xtClose);
        x.CloseElement(c4);
      end;

      x.CloseElement(c2);
    end;
    x.CloseElement(c1);
    x.CloseDocument;

    ShowMessage(IntToStr(GetTickCount - tc));

    x.SaveToFile('c:\test.xml');
  finally
    x.Free;
  end;
end;
  




И c:\test.xml : 374.5 mb


ShowMessage(IntToStr(GetTickCount - tc)) : 9719;

Это вполне удовлетворительно для моего задача!
...
Рейтинг: 0 / 0
Работа с PChar
    #39474241
Фотография defecator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
SOFT FOR YOUdefecator,

Я занят рефакторингом CrystalLUA. Юникод, x64, задел под ARM/FPC, немного оптимизаций. Вы же не в состоянии программировать на уровне. Приходится делать в одиночку )

Наконец-то занялся чем-то одним, молодец !
...
Рейтинг: 0 / 0
Работа с PChar
    #39474242
Alimkulov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rgreat,
Я бы не делал бы так. Вам известно, что происходит внутри SetLength()?
...
Рейтинг: 0 / 0
25 сообщений из 92, страница 2 из 4
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Работа с PChar
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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