powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / PHP Array VS Delphi Array
61 сообщений из 61, показаны все 3 страниц
PHP Array VS Delphi Array
    #39955781
Меня заинтересовало, а на сколько быстрее Delphi массивы по сравнению с PHP массивами.

Я долго думать не стал, и запилил тест... Оказывается, Delphi не быстрее , он медленнее в плане массивов...


Я поставил простые задачи(С права на снимке), и решил их с помощью стандартных средств Delphi и с помощью PHP.

Исходник проекта (Есть скомпилированный BUILD. VS 2017 redistributable)
https://cloud.mail.ru/public/4Bgr/GtGHhBuZ5

Исходник PHP 7.4.5 (52 мб) (Для компиляции НЕ нужна VS) (Портативный компилятор VS в комплекте)
https://cloud.mail.ru/public/31FY/4BWG5PjUs

Важные файлы там по пути
\7.4.5\src\mytest\(EnigneFunction.c\EnigneFunction.h)

Подключение на стороне Delphi файлик PHPRunner\Engine.pas
Код: 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.
unit Engine;

interface

uses
  Windows, Rtti, TypInfo, System.SysUtils, vcl.dialogs;

const
  dll = 'php7ts.dll';

type
  TPtr = Pointer;

  PPHPOptions = ^TPHPOptions;

  TPHPOptions = object
    SessionInit, SessionInit2, SizeZval: Integer;

    IS_UNDEF, IS_NULL, IS_FALSE, IS_TRUE, IS_LONG, IS_DOUBLE, IS_STRING, IS_ARRAY, IS_OBJECT, IS_RESOURCE, IS_REFERENCE, IS_CONSTANT_AST, IS_INDIRECT, IS_PTR, IS_ALIAS_PTR, IS_ERROR, IS_BOOL, IS_CALLABLE,
      IS_ITERABLE, IS_VOID, IS_NUMBER: UInt8;

    // Array\Class\...
    PDeclare, PUpdate, PUpdateStatic, PAssoc, PIndex, PNext, PConst, PConstClass, PProperty: UInt8;
    P: function(Operation: Integer; ptr: TPtr; TypeSet: Integer): Integer cdecl varargs;

    // Для print\echo и так далее .ub_write := function(...): Size_t; cdecl;
    ub_write: function(const Str: PAnsiChar; Len: Size_t): Size_t; cdecl;

    NewPzval: function(size: Size_t = 1): TPtr; cdecl;
    FreePzval: procedure(zv: TPtr); cdecl;

    // Извлекаем из zval* ифнормацию
    Zval_Type: function(zval: TPtr; &type: Integer): TPtr; cdecl; // convert zval* to zval* type
    Z_TYPE_P: function(zval: TPtr): Integer; cdecl; // return IS_NULL\IS_LONG\IS_STRING\...
    Z_STRVAL_P: function(zval: TPtr): PAnsiChar; cdecl; // Используйте функцию ZStr
    Z_LVAL_P: function(z: Pointer): NativeInt; cdecl;
    Z_DVAL_P: function(z: Pointer): Double; cdecl;
    ZVAL_DEREF: procedure(z: Pointer); cdecl;

    // Str : Строка с кодом.
    // Retval_ptr: Можно получить return кода.
    // String_name : Имя виртуального скрипт.
    // Handle_exceptions : Разрешить вывод ошибок.
    EvalCode: procedure(Str: UTF8String; Retval_ptr: TPtr; String_name: UTF8String; Handle_exceptions: Integer); cdecl;

    // Аналог  ini_set без возврата старого значения
    IniSet: procedure(const name, Value: UTF8String); cdecl;

    // Старый добрый print_r
    printR: function(Expr: TPtr; Indent: Integer): PAnsiChar; cdecl;

    // Регистрируем переменную глобально
    RegGlobal: procedure(&var: UTF8String; Val: TPtr); cdecl;

    // Регистрируем класс
    RegPHPClass: function(const Str: UTF8String): TPtr; cdecl; // return zend_class_entry *

    Zend_new_array: function(NSize: Cardinal = 12): TPtr; cdecl; // return zend_array *
    array_init_size: function(NSize: Cardinal = 12): TPtr; cdecl;
    array_count: function(zval: TPtr): uint32; cdecl;
    array_dup: function(zval: TPtr): TPtr; cdecl;
    array_destroy: procedure(zval: TPtr); cdecl;

    ArrayDelStr: function(zval: TPtr; const Key: UTF8String): NativeInt; cdecl;
    ArrayDelStr2: function(zval: TPtr; const Key: UTF8String; Len: NativeInt): NativeInt; cdecl;
    ArrayDelIndex: function(zval: TPtr; Key: NativeInt): NativeInt; cdecl;

    ArrayFindStr: function(zval: TPtr; const Key: UTF8String): TPtr; cdecl;
    ArrayGetIntStr: function(zval: TPtr; const Key: UTF8String): NativeInt; cdecl;
    ArrayGetDoubleStr: function(zval: TPtr; const Key: UTF8String): Double; cdecl;
    ArrayGetStringStr: function(zval: TPtr; const Key: UTF8String): PAnsiChar; cdecl;

    ArrayFindStr2: function(zval: TPtr; const Key: UTF8String; Len: NativeInt): TPtr; cdecl;
    ArrayGetIntStr2: function(zval: TPtr; const Key: UTF8String; Len: NativeInt): NativeInt; cdecl;
    ArrayGetDoubleStr2: function(zval: TPtr; const Key: UTF8String; Len: NativeInt): Double; cdecl;
    ArrayGetStringStr2: function(zval: TPtr; const Key: UTF8String; Len: NativeInt): PAnsiChar; cdecl;

    ArrayFindIndex: function(zval: TPtr; Key: NativeInt): TPtr; cdecl;
    ArrayGetIntIndex: function(zval: TPtr; Key: NativeInt): NativeInt; cdecl;
    ArrayGetDoubleIndex: function(zval: TPtr; Key: NativeInt): Double; cdecl;
    ArrayGetStringIndex: function(zval: TPtr; Key: NativeInt): PAnsiChar; cdecl;

    array_set_zval_key: function(ht, Arg, Value: TPtr): Integer; cdecl;

    // Вместо, использовать FreePHP. Так как надо освободить библиотеку PHP
    &destructor: procedure(); cdecl;

    // Возвратим всем понятный строковой тип
    function ZStr(zval: TPtr): STRING;
  end;

  {
    var arr := array_init_size();
    P(PAssoc, arr, IS_LONG, UTF8String('Key1'), 1 * 10);
    P(PAssoc, arr, IS_LONG, UTF8String('Key2'), 2 * 10);
    P(PAssoc, arr, IS_STRING, UTF8String('Key3'), UTF8String('Hello Key3'));

    P(PIndex, arr, IS_LONG, 0, 4 * 10);
    P(PIndex, arr, IS_LONG, 1, 5 * 10);
    P(PIndex, arr, IS_STRING, 2, UTF8String('Hello index 2'));

    P(PNext, arr, IS_LONG, 7 * 10);
    P(PNext, arr, IS_LONG, 8 * 10);
    P(PNext, arr, IS_STRING, UTF8String('Hello index 5'));

    ShowMessage('Count: ' + array_count(arr).ToString + #13 + printR(arr, 0));


    // Set global const
    P(PConst, nil, IS_STRING, UTF8String('ConstGlobal'), UTF8String('PHP Const Global'));

    // Set global function pre(...)
    RegFunction(nil, 'pre', @PreHandler, nil, 0, 0);

    // New Class Test
    var RegClass := RegPHPClass('Test');

    // Set function callBack
    RegFunction(RegClass, 'pre', @PreHandler, nil, 0, ZEND_ACC_PUBLIC);

    // Set const class Test::ConstName = Hello
    P(PConstClass, RegClass, IS_STRING, UTF8String('ConstName'), UTF8String('Hello'));

    // Set static. Test::$StaticLong
    P(PDeclare, RegClass, IS_LONG, UTF8String('StaticLong'), 10, ZEND_ACC_STATIC);

    // Update static. Test::$StaticLong. Fatal error if Declare is not installed
    P(PUpdateStatic, RegClass, IS_LONG, UTF8String('StaticLong'), 2020);

    // Set default class prop (new Test)->Str = Val Set
    P(PDeclare, RegClass, IS_STRING, UTF8String('Str'), UTF8String('Val Set'), ZEND_ACC_PUBLIC);

    // Init Class Test to zval *
    var NewClas := NewPzval;
    object_init_ex(NewClas, RegClass);

    // Example of other initializations
    P(PUpdate, RegClass, IS_NULL,   UTF8String('UpdateNull'),   NewClas);
    P(PUpdate, RegClass, IS_LONG,   UTF8String('UpdateLong'),   NewClas, 2020);
    P(PUpdate, RegClass, IS_BOOL,   UTF8String('UpdateBool'),   NewClas, True);
    P(PUpdate, RegClass, IS_DOUBLE, UTF8String('UpdateDouble'), NewClas, Double(Pi));
    P(PUpdate, RegClass, IS_STRING, UTF8String('UpdateString'), NewClas, UTF8String('Hello'));

    ShowMessage(string(UTF8String(printR(NewClas, 0))));  // PrintClass
    free(NewClas, 0);  // Free Init Class
  }

function LoadPHP(const DLLPath: PChar; Name, Pretty_name: UTF8String; var LibHandle: HMODULE): PPHPOptions;
procedure FreePHP(var php: PPHPOptions; var LibHandle: HMODULE);

var
  php: PPHPOptions;
  LibHandle: HMODULE;

implementation

function TPHPOptions.ZStr(zval: TPtr): STRING;
begin
  Result := string(UTF8String(Z_STRVAL_P(zval)));
end;

// -------------------------------------------------------------------
function LoadPHP(const DLLPath: PChar; Name, Pretty_name: UTF8String; var LibHandle: HMODULE): PPHPOptions;
var
  init: function(Name, Pretty_name: UTF8String): PPHPOptions; cdecl;
begin
  if FileExists(DLLPath) then
  begin
    LibHandle := LoadLibrary(DLLPath);

    if LibHandle <= 32 then
      RaiseLastOSError;

    @init := GetProcAddress(LibHandle, 'PHPInit');

    if @init = Nil then
      raise EListError.Create('NotFound PHPInit: ' + DLLPath);

    Result := init(Name, Pretty_name);
  end
  else
    raise EListError.Create('NotFound: ' + DLLPath);
end;

procedure FreePHP(var php: PPHPOptions; var LibHandle: HMODULE);
begin
  if @php.&destructor <> nil then
    php.&destructor;

  if LibHandle > 32 then
  begin
    FreeLibrary(LibHandle);
    LibHandle := 0;
  end;
end;

initialization

try
  php := LoadPHP(dll, 'cli', 'TestEval', LibHandle);

  if (php.SessionInit <> 1) and (php.SessionInit2 <> 1) then
  begin
    ShowMessage('Библиотека php не иницилизирована');
    ExitProcess(0);
  end;

except
  on E: Exception do
  begin
    ShowMessage(E.ClassName + ' : ' + E.Message);
    ExitProcess(0);
  end;
end;

finalization

FreePHP(php, LibHandle);

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.
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.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
276.
277.
278.
279.
280.
281.
282.
283.
284.
285.
286.
287.
288.
289.
290.
291.
292.
unit PHPForm;

interface

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

type
  TForm1 = class(TForm)
    Code: TMemo;
    Log: TMemo;
    EvalCode: TButton;
    PHPArrayLog: TMemo;
    DelphiArrayLog: TMemo;
    PHPSpeedArr: TButton;
    DelphiSpeedArr: TButton;
    procedure EvalCodeClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure PHPSpeedArrClick(Sender: TObject);
    procedure DelphiSpeedArrClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }

    function PHPLineFill: AnsiString;
    function PHPLineFillString: AnsiString;
    function PHPLineFillStringIndex: AnsiString;
    function PHPLineFillStringString: AnsiString;
    function PHPLineFillMul: AnsiString;

    function DelphiLineFill: AnsiString;
    function DelphiLineFillString: AnsiString;
    function DelphiLineFillStringIndex: AnsiString;
    function DelphiLineFillStringString: AnsiString;
    function DelphiLineFillMul: AnsiString;
  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;

procedure TForm1.EvalCodeClick(Sender: TObject);
begin
  with php^ do
  begin
    EvalCode(Code.Text, nil, 'Test Runner', 1);
  end;
end;

function ub_write(const Str: PAnsiChar; Len: Size_t): Size_t cdecl;
begin
  Form1.Log.Lines.Add(UTF8String(Str));
  Result := Len;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  php^.ub_write := ub_write;
end;

function TForm1.PHPLineFill: AnsiString;
var
  arr: Pointer;
  i, r: integer;
begin
  QueryPerformanceCounter(T1);
  with php^ do
  begin
    arr := array_init_size(1000000);
    for r := 0 to 3 do
      for i := 0 to 1000000 do
        P(PIndex, arr, IS_LONG, i, i);
    array_destroy(arr);
  end;
  Result := PrintTime(T1);
end;

function TForm1.PHPLineFillString: AnsiString;
var
  arr: Pointer;
  i, r: integer;
begin
  QueryPerformanceCounter(T1);
  with php^ do
  begin
    arr := array_init_size(1000000);
    for r := 0 to 3 do
      for i := 0 to 1000000 do
        P(PIndex, arr, IS_STRING, i, 'ValueString' + i.ToString);
    array_destroy(arr);
  end;
  Result := PrintTime(T1);
end;

function TForm1.PHPLineFillStringIndex: AnsiString;
var
  arr: Pointer;
  i, r: integer;
begin
  QueryPerformanceCounter(T1);
  with php^ do
  begin
    arr := array_init_size(1000000);
    for r := 0 to 3 do
      for i := 0 to 1000000 do
        P(PAssoc, arr, IS_LONG, 'KeyString' + i.ToString, i);
    array_destroy(arr);
  end;
  Result := PrintTime(T1);
end;

function TForm1.PHPLineFillStringString: AnsiString;
var
  arr: Pointer;
  i, r: integer;
begin
  QueryPerformanceCounter(T1);
  with php^ do
  begin
    arr := array_init_size(1000000);
    for r := 0 to 3 do
      for i := 0 to 1000000 do
        P(PAssoc, arr, IS_STRING, 'KeyString' + i.ToString, 'ValueString' + i.ToString);
    array_destroy(arr);
  end;
  Result := PrintTime(T1);
end;

function TForm1.PHPLineFillMul: AnsiString;
var
  arr: Pointer;
  i, r: integer;
begin
  QueryPerformanceCounter(T1);
  with php^ do
  begin
    arr := array_init_size(1000000);
    for r := 0 to 3 do
      for i := 0 to 1000000 do
      begin
        P(PIndex, arr, IS_LONG, i, i);
        P(PIndex, arr, IS_LONG, i, ArrayGetIntIndex(arr, i) * i);
      end;
    array_destroy(arr);
  end;
  Result := PrintTime(T1);
end;

procedure TForm1.PHPSpeedArrClick(Sender: TObject);
begin
  with PHPArrayLog.Lines do
  begin
    Add('PHP. Каждое действие выполняется по 3 раза от 0 до 1000000');
    Add('Arr[$i] = $i;                                            Time: ' + PHPLineFill);
    Add('Arr[$i] = ''ValueString'' + $i;                    Time: ' + PHPLineFillString);
    Add('Arr[''KeyString'' + $i] = $i;                       Time: ' + PHPLineFillStringIndex);
    Add('Arr[''KeyString'' + $i] = ''TestString'' + $i; Time: ' + PHPLineFillStringString);
    Add('Arr[i] = i; & Arr[i] = Arr[i] * Arr[i];      . Time: ' + PHPLineFillMul);
  end;
end;

function TForm1.DelphiLineFill: AnsiString;
var
  arr: Pointer;
  i, r: integer;

  l: TDictionary<integer, integer>;
begin
  QueryPerformanceCounter(T1);

  l := TDictionary<integer, integer>.Create(1000000);
  for r := 0 to 3 do
    for i := 0 to 1000000 do
      l.AddOrSetValue(i, i);

  l.Free;
  Result := PrintTime(T1);
end;

function TForm1.DelphiLineFillString: AnsiString;
var
  arr: Pointer;
  i, r: integer;

  l: TDictionary<integer, string>;
begin
  QueryPerformanceCounter(T1);

  l := TDictionary<integer, string>.Create(1000000);
  for r := 0 to 3 do
    for i := 0 to 1000000 do
      l.AddOrSetValue(i, 'ValueString' + i.ToString);

  l.Free;
  Result := PrintTime(T1);
end;

function TForm1.DelphiLineFillStringIndex: AnsiString;
var
  arr: Pointer;
  i, r: integer;

  l: TDictionary<string, integer>;
begin
  QueryPerformanceCounter(T1);

  l := TDictionary<string, integer>.Create(1000000);
  for r := 0 to 3 do
    for i := 0 to 1000000 do
      l.AddOrSetValue('KeyString' + i.ToString, i);

  l.Free;
  Result := PrintTime(T1);
end;

function TForm1.DelphiLineFillStringString: AnsiString;
var
  arr: Pointer;
  i, r: integer;

  l: TDictionary<string, string>;
begin
  QueryPerformanceCounter(T1);

  l := TDictionary<string, string>.Create(1000000);
  for r := 0 to 3 do
    for i := 0 to 1000000 do
      l.AddOrSetValue('KeyString' + i.ToString, 'ValueString' + i.ToString);

  l.Free;
  Result := PrintTime(T1);
end;

function TForm1.DelphiLineFillMul: AnsiString;
var
  arr: Pointer;
  i, r: integer;

  l: TDictionary<integer, integer>;
begin
  QueryPerformanceCounter(T1);

  l := TDictionary<integer, integer>.Create(1000000);
  for r := 0 to 3 do
    for i := 0 to 1000000 do
    begin
      l.AddOrSetValue(i, i);
      l.AddOrSetValue(i, l.Items[i] * i);
    end;

  l.Free;
  Result := PrintTime(T1);
end;

procedure TForm1.DelphiSpeedArrClick(Sender: TObject);
begin
  with DelphiArrayLog.Lines do
  begin
    Add('Delphi. Каждое действие выполняется по 3 раза от 0 до 1000000');
    Add('Arr[$i] = $i;                                            Time: ' + DelphiLineFill);
    Add('Arr[$i] = ''ValueString'' + $i;                    Time: ' + DelphiLineFillString);
    Add('Arr[''KeyString'' + $i] = $i;                       Time: ' + DelphiLineFillStringIndex);
    Add('Arr[''KeyString'' + $i] = ''TestString'' + $i; Time: ' + DelphiLineFillStringString);
    Add('Arr[i] = i; & Arr[i] = Arr[i] * Arr[i];      . Time: ' + DelphiLineFillMul);
  end;

end;

end.



Я выбрал TDictionary так как он подходит как аналог - лучше всего. Можно менять как тип ключа, так и значения. Что аналогично PHP


Примеры очень простые, тут даже нету realloca (Я думаю результаты будут ещё хуже у Delphi. Но можно проверить если будет интересно, убрав выделения 1000000)
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39955782
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Массивы и TDictionary... Какая связь?
Никакой. Ну как всегда.
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39955783
rgreat,

А тут идёт тестирование хэш таблиц, которые могут принимать в качестве ключа ещё и строковой тип.
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39955784
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВсеРазумный,

И причем тут массивы? Правильно - не при чем.
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39955785
rgreat,

Коллекционные массивы. Они в принципе Они. Раз Они и в PHP как Массивы
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39955786
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВсеРазумный,

Когда я вижу реализацию Arr[i] = i; & Arr[i] = Arr[i] * Arr[i]; через TDictionary меня пробивает на ржач.
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39955787
rgreat,

Это всего лишь тест. Как бы для тебя он смешным не был, но извлечение из TDictionary тебе не избежать

И как раз, мы извлекаем значение, изменяем его, и шлём назад.
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39955788
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВсеРазумный,

Ничего что реально через реальные массивы все будет работать раз в n-дцать быстрей?

Ну протестируй еще умножение двух чисел через передачу их в виде файлов на фтп и тоже обзови тестом массивов.
Это же просто тест. (с)
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39955789
rgreat,

Но тест ведь объективный ? По сравнению с PHP. Разве нет?

Извлечение по индексу идёт функцией
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
function TDictionary<TKey,TValue>.GetItem(const Key: TKey): TValue;
var
  index: Integer;
begin
  index := GetBucketIndex(Key, Hash(Key));
  if index < 0 then
    raise EListError.CreateRes(@SGenericItemNotFound);
  Result := FItems[index].Value;
end;



В PHP же
Код: plaintext
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.
#define HT_HASH_EX(data, idx) \
	((uint32_t*)(data))[(int32_t)(idx)]

# define HT_HASH_TO_BUCKET_EX(data, idx) \
	((Bucket*)((char*)(data) + (idx)))

#define Z_LVAL(zval)				(zval).value.lval
#define Z_LVAL_P(zval_p)			Z_LVAL(*(zval_p))
#define Z_TYPE(zval)				zval_get_type(&(zval))
#define Z_NEXT(zval)				(zval).u2.next
#define HT_FLAGS(ht) (ht)->u.flags

int ArrayGetIntIndex(zval *Arr, zend_ulong Key) {
	zval *z = zend_hash_index_find(Z_ARRVAL_P(Arr), Key);
	return (z!=NULL) ? Z_LVAL_P(z) : 0;
}

static zend_always_inline Bucket *zend_hash_index_find_bucket(const HashTable *ht, zend_ulong h)
{
	uint32_t nIndex;
	uint32_t idx;
	Bucket *p, *arData;

	arData = ht->arData;
	nIndex = h | ht->nTableMask;
	idx = HT_HASH_EX(arData, nIndex);
	while (idx != HT_INVALID_IDX) {
		ZEND_ASSERT(idx < HT_IDX_TO_HASH(ht->nTableSize));
		p = HT_HASH_TO_BUCKET_EX(arData, idx);
		if (p->h == h && !p->key) {
			return p;
		}
		idx = Z_NEXT(p->val);
	}
	return NULL;
}


ZEND_API zval* ZEND_FASTCALL zend_hash_index_find(const HashTable *ht, zend_ulong h)
{
	Bucket *p;

	IS_CONSISTENT(ht);

	if (HT_FLAGS(ht) & HASH_FLAG_PACKED) {
		if (h < ht->nNumUsed) {
			p = ht->arData + h;
			if (Z_TYPE(p->val) != IS_UNDEF) {
				return &p->val;
			}
		}
		return NULL;
	}

	p = zend_hash_index_find_bucket(ht, h);
	return p ? &p->val : NULL;
}

static zend_always_inline zend_uchar zval_get_type(const zval* pz) {
	return pz->u1.v.type;
}

static void _zend_is_inconsistent(const HashTable *ht, const char *file, int line)
{
	if ((HT_FLAGS(ht) & HASH_FLAG_CONSISTENCY) == HT_OK) {
		return;
	}
	switch (HT_FLAGS(ht) & HASH_FLAG_CONSISTENCY) {
		case HT_IS_DESTROYING:
			zend_output_debug_string(1, "%s(%d) : ht=%p is being destroyed", file, line, ht);
			break;
		case HT_DESTROYED:
			zend_output_debug_string(1, "%s(%d) : ht=%p is already destroyed", file, line, ht);
			break;
		case HT_CLEANING:
			zend_output_debug_string(1, "%s(%d) : ht=%p is being cleaned", file, line, ht);
			break;
		default:
			zend_output_debug_string(1, "%s(%d) : ht=%p is inconsistent", file, line, ht);
			break;
	}
	ZEND_ASSERT(0);
}
#define IS_CONSISTENT(a) _zend_is_inconsistent(a, __FILE__, __LINE__);



И это всё равно быстрее
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39955790
rgreat,

Ну реальные массивы к сожалению не поддерживают Arr[STRING] = STRING по этому, реальные массивы не будут работать быстрее уже. Потому что тебе придётся использовать TDictionary
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39955791
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хочешь сравнить работу конкретных реализаций словарей - на здоровье.

Но не надо сравнивать теплое с мягким.
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39955792
rgreat,

Массивы для всех разные. К примеру для тебя массивы это классический array для кого - то TDictionary Это ведь массив в любом случае, хоть коллекционный

https://swiftbook.ru/content/languageguide/collection-types/

swiftbookSwift обеспечивает три основных типа коллекций - это Массивы, Множества и Словари для хранения коллекций значений.
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39955793
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВсеРазумный,

Код: 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.
program Project1;

{$APPTYPE CONSOLE}

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, Classes, Generics.Collections, Indexes;


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 DelphiLineFillMul: AnsiString;
var
  arr: Pointer;
  i, r: integer;

  l: TDictionary<integer, integer>;
begin
  QueryPerformanceCounter(T1);

  l := TDictionary<integer, integer>.Create(1000000);
  for r := 0 to 3 do
    for i := 0 to 1000000 do
    begin
      l.AddOrSetValue(i, i);
      l.AddOrSetValue(i, l.Items[i] * i);
    end;

  l.Free;
  Result := PrintTime(T1);
end;


function DelphiLineFillMulArr: AnsiString;
var
  arr: Pointer;
  i, r: integer;

  l: TArrayEx<integer>;
begin
  QueryPerformanceCounter(T1);

  l.Count:=1000000;
  for r := 0 to 3 do
    for i := 0 to 1000000 do
    begin
      l.Items[i]:=i;
      l.Items[i]:=l.Items[i]*i;
    end;

  Result := PrintTime(T1);
end;

begin
  WriteLn(DelphiLineFillMul);
  WriteLn(DelphiLineFillMulArr);
  Readln;
end.


0.929075
0.004351

Но ты можешь продолжать работать через словари. На здоровье.
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39955794
rgreat,

Скачал твоё поделие, попробовал.. Эм... А разница в чём? У меня не в чём
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39955795
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ты бы "мою" функцию ради приличий хотя бы вызвал, что-ли. ;)

И работай через .items - так еще на порядок скорость поднимешь ибо не будет проперти дергать зазря.
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39955796
rgreat,

Да, извини... Видно я откат нажал, и не заметил..


А всё равно в качестве ключа нельзя использовать string
Код: pascal
1.
l.Items['KeyString' + i.ToString] := 'ValueString' + i.ToString;



Тогда это ничем не отличается от (кроме некоторых плюшек маловажных)
Код: pascal
1.
 l: TArray<string>;
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39955798
rgreat,

Убрал Я инициализацию количество элементов, включая и в твоём примере


Всё таки можно удивится! На сколько быстрыми сделали хэш таблицы в PHP




Код: 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.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
276.
277.
278.
279.
280.
281.
282.
283.
284.
285.
286.
287.
288.
289.
290.
291.
292.
293.
294.
295.
296.
297.
298.
299.
300.
301.
302.
303.
304.
305.
306.
307.
308.
309.
310.
311.
312.
unit PHPForm;

interface

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

type
  TForm1 = class(TForm)
    Code: TMemo;
    Log: TMemo;
    EvalCode: TButton;
    PHPArrayLog: TMemo;
    DelphiArrayLog: TMemo;
    PHPSpeedArr: TButton;
    DelphiSpeedArr: TButton;
    procedure EvalCodeClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure PHPSpeedArrClick(Sender: TObject);
    procedure DelphiSpeedArrClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }

    function PHPLineFill: AnsiString;
    function PHPLineFillString: AnsiString;
    function PHPLineFillStringIndex: AnsiString;
    function PHPLineFillStringString: AnsiString;
    function PHPLineFillMul: AnsiString;

    function DelphiLineFill: AnsiString;
    function DelphiLineFillString: AnsiString;
    function DelphiLineFillStringIndex: AnsiString;
    function DelphiLineFillStringString: AnsiString;
    function DelphiLineFillMul: AnsiString;
  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;

procedure TForm1.EvalCodeClick(Sender: TObject);
begin
  with php^ do
  begin
    EvalCode(Code.Text, nil, 'Test Runner', 1);
  end;
end;

function ub_write(const Str: PAnsiChar; Len: Size_t): Size_t cdecl;
begin
  Form1.Log.Lines.Add((Str));
  Result := Len;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  php^.ub_write := ub_write;
end;

function TForm1.PHPLineFill: AnsiString;
var
  arr: Pointer;
  i, r: integer;
begin
  QueryPerformanceCounter(T1);
  with php^ do
  begin
    arr := array_init_size();
    for r := 0 to 3 do
      for i := 0 to 1000000 do
        P(PIndex, arr, IS_LONG, i, i);
    array_destroy(arr);
  end;
  Result := PrintTime(T1);
end;

function TForm1.PHPLineFillString: AnsiString;
var
  arr: Pointer;
  i, r: integer;
begin
  QueryPerformanceCounter(T1);
  with php^ do
  begin
    arr := array_init_size();
    for r := 0 to 3 do
      for i := 0 to 1000000 do
        P(PIndex, arr, IS_STRING, i, 'ValueString' + i.ToString);
    array_destroy(arr);
  end;
  Result := PrintTime(T1);
end;

function TForm1.PHPLineFillStringIndex: AnsiString;
var
  arr: Pointer;
  i, r: integer;
begin
  QueryPerformanceCounter(T1);
  with php^ do
  begin
    arr := array_init_size();
    for r := 0 to 3 do
      for i := 0 to 1000000 do
        P(PAssoc, arr, IS_LONG, 'KeyString' + i.ToString, i);
    array_destroy(arr);
  end;
  Result := PrintTime(T1);
end;

function TForm1.PHPLineFillStringString: AnsiString;
var
  arr: Pointer;
  i, r: integer;
begin
  QueryPerformanceCounter(T1);
  with php^ do
  begin
    arr := array_init_size();
    for r := 0 to 3 do
      for i := 0 to 1000000 do
        P(PAssoc, arr, IS_STRING, 'KeyString' + i.ToString, 'ValueString' + i.ToString);
    array_destroy(arr);
  end;
  Result := PrintTime(T1);
end;

function TForm1.PHPLineFillMul: AnsiString;
var
  arr: Pointer;
  i, r: integer;
begin
  QueryPerformanceCounter(T1);
  with php^ do
  begin
    arr := array_init_size();
    for r := 0 to 3 do
      for i := 0 to 1000000 do
      begin
        P(PIndex, arr, IS_LONG, i, i);
        P(PIndex, arr, IS_LONG, i, ArrayGetIntIndex(arr, i) * i);
      end;
    array_destroy(arr);
  end;
  Result := PrintTime(T1);
end;

procedure TForm1.PHPSpeedArrClick(Sender: TObject);
begin
  with PHPArrayLog.Lines do
  begin
    Add('PHP. Каждое действие выполняется по 3 раза от 0 до 1000000');
    Add('Arr[$i] = $i;                                            Time: ' + PHPLineFill);
    Add('Arr[$i] = ''ValueString'' + $i;                    Time: ' + PHPLineFillString);
    Add('Arr[''KeyString'' + $i] = $i;                       Time: ' + PHPLineFillStringIndex);
    Add('Arr[''KeyString'' + $i] = ''TestString'' + $i; Time: ' + PHPLineFillStringString);
    Add('Arr[i] = i; & Arr[i] = Arr[i] * Arr[i];      . Time: ' + PHPLineFillMul);
  end;
end;

function TForm1.DelphiLineFill: AnsiString;
var
  arr: Pointer;
  i, r: integer;

  l: TDictionary<integer, integer>;
begin
  QueryPerformanceCounter(T1);

  l := TDictionary<integer, integer>.Create();
  for r := 0 to 3 do
    for i := 0 to 1000000 do
      l.AddOrSetValue(i, i);

  l.Free;
  Result := PrintTime(T1);
end;

function TForm1.DelphiLineFillString: AnsiString;
var
  arr: Pointer;
  i, r: integer;

  l: TDictionary<integer, string>;
begin
  QueryPerformanceCounter(T1);

  l := TDictionary<integer, string>.Create();
  for r := 0 to 3 do
    for i := 0 to 1000000 do
      l.AddOrSetValue(i, 'ValueString' + i.ToString);

  l.Free;
  Result := PrintTime(T1);
end;

function TForm1.DelphiLineFillStringIndex: AnsiString;
var
  arr: Pointer;
  i, r: integer;

  l: TDictionary<string, integer>;
begin
  QueryPerformanceCounter(T1);

  l := TDictionary<string, integer>.Create();
  for r := 0 to 3 do
    for i := 0 to 1000000 do
      l.AddOrSetValue('KeyString' + i.ToString, i);

  l.Free;
  Result := PrintTime(T1);
end;

function TForm1.DelphiLineFillStringString: AnsiString;
var
  arr: Pointer;
  i, r: integer;

  l: TDictionary<string, string>;
begin
  QueryPerformanceCounter(T1);

  l := TDictionary<string, string>.Create();
  for r := 0 to 3 do
    for i := 0 to 1000000 do
      l.AddOrSetValue('KeyString' + i.ToString, 'ValueString' + i.ToString);

  l.Free;
  Result := PrintTime(T1);
end;

function TForm1.DelphiLineFillMul: AnsiString;
var
  arr: Pointer;
  i, r: integer;

  l: TDictionary<integer, integer>;
begin
  QueryPerformanceCounter(T1);

  l := TDictionary<integer, integer>.Create();
  for r := 0 to 3 do
    for i := 0 to 1000000 do
    begin
      l.AddOrSetValue(i, i);
      l.AddOrSetValue(i, l.Items[i] * i);
    end;
  l.Free;
  Result := PrintTime(T1);
end;

function DelphiLineFillMulArr: AnsiString;
var
  arr: Pointer;
  i, r: integer;

  l: TArrayEx<integer>;
begin
  QueryPerformanceCounter(T1);

  for r := 0 to 3 do
    for i := 0 to 1000000 do
    begin
      l.Add(i);
      l.Items[i] := l.Items[i] * i;
    end;

  Result := PrintTime(T1);
end;

procedure TForm1.DelphiSpeedArrClick(Sender: TObject);
begin
  with DelphiArrayLog.Lines do
  begin
    Add('Delphi. Каждое действие выполняется по 3 раза от 0 до 1000000');
    Add('Arr[$i] = $i;                                            Time: ' + DelphiLineFill);
    Add('Arr[$i] = ''ValueString'' + $i;                    Time: ' + DelphiLineFillString);
    Add('Arr[''KeyString'' + $i] = $i;                       Time: ' + DelphiLineFillStringIndex);
    Add('Arr[''KeyString'' + $i] = ''TestString'' + $i; Time: ' + DelphiLineFillStringString);
    Add('Arr[i] = i; & Arr[i] = Arr[i] * Arr[i];      . Time: ' + DelphiLineFillMul);

    Add('rgreat TArrayEx<integer>      . Time: ' + DelphiLineFillMulArr);
  end;

end;

end.



rgreat 0.180867 против 0.199431 от php

Чистая индексация даёт о себе знать
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39955799
misha mike
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39955800
Надо учесть тот факт, что добавление идёт через такую функцию

Код: plaintext
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.
#define __PDeclare 1
#define __PUpdate 2
#define __PUpdateStatic 3
#define __PAssoc 4
#define __PConst 5
#define __PConstClass 6
#define __PProperty 7
#define __PIndex 8
#define __PNext 9


int __P(int Operation, void * ptr, int TypeSet) {
	int ret = 0;
	
	va_list args;
	va_start(args, TypeSet);
	
	char *key;
	int len;
	if(Operation >= __PDeclare && Operation <= __PProperty) {
		key = va_arg(args, char*);
		len = strlen(key);
	}
	
	switch(Operation) {
		case __PDeclare: switch(TypeSet) {
				_ClassSet(IS_NULL,   declare, _null  , int);
				_ClassSet(IS_PTR,    declare,        , zval *   , va_arg(args, int));
				_ClassSet(_IS_BOOL,  declare, _bool  , zend_bool, va_arg(args, int));
				_ClassSet(IS_LONG,   declare, _long  , zend_long, va_arg(args, int));
				_ClassSet(IS_DOUBLE, declare, _double, double   , va_arg(args, int));
				_ClassSet(IS_STRING, declare, _string, char *   , va_arg(args, int));
			}
		break;
		case __PUpdate: switch(TypeSet) {
				_ClassSet2(IS_VOID,   unset,           );
				_ClassSet2(IS_NULL,   update,	_null  );
				_ClassSet2(IS_PTR,    update,          , va_arg(args, zval *));
				_ClassSet2(IS_LONG,   update,   _long  , va_arg(args, zend_long));
				_ClassSet2(_IS_BOOL,  update,   _bool  , va_arg(args, zend_bool));
				_ClassSet2(IS_DOUBLE, update,   _double, va_arg(args, double));
				_ClassSet2(IS_STRING, update,   _string, va_arg(args, char *));
				_ClassSet2(100,       update,   _str   , va_arg(args, zend_string *));
			}
		break;
		case __PUpdateStatic: switch(TypeSet) {
				_ClassSet3(IS_NULL,   update_static, _null);
				_ClassSet3(IS_PTR,    update_static,        , va_arg(args, zval *));
				_ClassSet3(_IS_BOOL,  update_static, _bool  , va_arg(args, zend_bool));
				_ClassSet3(IS_LONG,   update_static, _long  , va_arg(args, zend_long));
				_ClassSet3(IS_DOUBLE, update_static, _double, va_arg(args, double));
				_ClassSet3(IS_STRING, update_static, _string, va_arg(args, char *));
			}
		break;
		case __PAssoc:
			switch(TypeSet) {
				_Arr1(assoc,  IS_NULL,     null);
				_Arr1(assoc,  IS_LONG,     long,     va_arg(args, zend_long));
				_Arr1(assoc,  IS_DOUBLE,   double,   va_arg(args, double));
				_Arr1(assoc, _IS_BOOL,     bool,     va_arg(args, zend_bool));
				_Arr1(assoc,  IS_STRING,   string,   va_arg(args, char *));
				_Arr1(assoc,  IS_PTR,      zval,     va_arg(args, zval *));
				_Arr1(assoc,  IS_RESOURCE, resource, va_arg(args, zend_resource *));
				_Arr1(assoc,  100,         str,      va_arg(args, zend_string *));
			}
		break;
		case __PIndex:
			int key2 = va_arg(args, int);
			switch(TypeSet) {
				_Arr2(index,  IS_NULL,     null,     key2);
				_Arr2(index,  IS_LONG,     long,     key2, va_arg(args, zend_long));
				_Arr2(index,  IS_DOUBLE,   double,   key2, va_arg(args, double));
				_Arr2(index, _IS_BOOL,     bool,     key2, va_arg(args, zend_bool));
				_Arr2(index,  IS_STRING,   string,   key2, va_arg(args, char *));
				_Arr2(index,  IS_PTR,      zval,     key2, va_arg(args, zval *));
				_Arr2(index,  IS_RESOURCE, resource, key2, va_arg(args, zend_resource *));
				_Arr2(index,  100,         str,      key2, va_arg(args, zend_string *));
			}
		break;
		case __PNext:
			switch(TypeSet) {
				_Arr3(next,  IS_NULL,     null);
				_Arr3(next,  IS_LONG,     long,     va_arg(args, zend_long));
				_Arr3(next,  IS_DOUBLE,   double,   va_arg(args, double));
				_Arr3(next, _IS_BOOL,     bool,     va_arg(args, zend_bool));
				_Arr3(next,  IS_STRING,   string,   va_arg(args, char *));
				_Arr3(next,  IS_PTR,      zval,     va_arg(args, zval *));
				_Arr3(next,  IS_RESOURCE, resource, va_arg(args, zend_resource *));
				_Arr3(next,  100,         str,      va_arg(args, zend_string *));
			}
		break;
		case __PConst:
			switch(TypeSet) {
				_MacrosComplit2(IS_NULL,   null);
				_MacrosComplit3(IS_LONG,   long,   zend_long);
				_MacrosComplit3(IS_DOUBLE, double, double);
				_MacrosComplit3(_IS_BOOL,  bool,   zend_bool);
				_MacrosComplit3(IS_STRING, string, char *);
				case IS_PTR:
					int flags3 = va_arg(args, int); 
					int module_numbe3 = va_arg(args, int);
					
					zend_constant c;
					
					ZVAL_ZVAL(&c.value, va_arg(args, zval *), 1, 0);
					
					ZEND_CONSTANT_SET_FLAGS(&c, flags3, module_numbe3);
					
					c.name = zend_string_init_interned(key, len, flags3 & CONST_PERSISTENT);
					zend_register_constant(&c);
				break;
			};
		break;
		case __PConstClass:
			switch(TypeSet) {
				_MacrosComplit(IS_NULL,    _null);
				_MacrosComplit(IS_LONG,    _long,   va_arg(args, zend_long));
				_MacrosComplit(IS_DOUBLE,  _double, va_arg(args, double)); 
				_MacrosComplit(_IS_BOOL,   _bool,   va_arg(args, zend_bool));
				_MacrosComplit(IS_STRING,  _string, va_arg(args, char *));
				_MacrosComplit(IS_PTR,            , va_arg(args, zval *));
			};	
		break;
		case __PProperty:
			switch(TypeSet) {
				Prop(IS_NULL,     null);
				Prop(IS_LONG,     long,     va_arg(args, zend_long));
				Prop(IS_DOUBLE,   double,   va_arg(args, double));
				Prop(_IS_BOOL,    bool,     va_arg(args, zend_bool));
				Prop(IS_STRING,   string,   va_arg(args, char *));
				Prop(IS_PTR,      zval,     va_arg(args, zval *));
				Prop(IS_RESOURCE, resource, va_arg(args, zend_resource *));
				Prop(100,         str,      va_arg(args, zend_string *));
			};	
		break;
	}
	
	va_end(args);
	return ret;	
}



И возможно, на чистом c\c++ было бы быстрее
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39955801
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВсеРазумный

rgreat 0.180867 против 0.199431 от php
Нефиг портить мой код.
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39955802
rgreat,

Я его не испортил. Я его привёл в рабочий вид. Именно так его и будут использовать - если будут. :D

Я же говорю, в твоём коде нет смысла, когда есть

Код: pascal
1.
2.
3.
4.
var
 arr = TArray<Integer>;
begin
 SetLength(arr, 1000000);
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39955821
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВсеРазумный
TDictionary

это не массив
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39955841
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВсеРазумный,

авторНо тест ведь объективный ? По сравнению с PHP. Разве нет?
Когда вы говорите такое чувство что вы бредите
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39955910
makhaon
Когда вы говорите такое чувство что вы бредите



Нет, это увы - вы бредете.

1) Устанавливаем значение в индекс
2) Изымаем (Просто для примера Понимаете? Вам не избежать изъятия по индексу)
2) Просто для примера умножаем и кладёт обратно.


И это проворачиваем на zend array и delphi. По этому он объективный.




X11,
Да вот тут ссылку скидывали

https://habr.com/ru/post/282902/

MrShoorИтак мы подготовили массив из скажем 10 bucket-ов.

Ой.. Везде там коллекция упоминается как массив. Каак же так))
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39955912
Ну и в php zend array там тоже bucket тут я выложил как это работает для индексов

22130423
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39955915
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rgreat
Массивы и TDictionary... Какая связь?

Словарь - это частный случай ассоциативного массива.

з.ы.

Не спорь с Няшиком. Чувак берет сишную библиотеку с реализацией ассоциативного массива и на серьёзных щщах говорит, что это PHP.

...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39955919
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Няшик, а почему ты в функцию P(), ожидающую последовательность байт в UTF-8, передаешь последовательность в UTF-16? Подозреваю, что такие последовательности будут интерпретированы, как однобайтовые
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39955920
Kazantsev Alexey
щщах говорит, что это PHP.


ВсеРазумный
php zend array


ВсеРазумный
zend array



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


ВсеРазумный
Разумеется с чистым общением ZendAPI без интерпретатора. Дабы знать на сколько поссосанная система в Delphi
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39955921
Kazantsev Alexey
Няшик, а почему ты в функцию P(), ожидающую последовательность байт в UTF-8, передаешь последовательность в UTF-16? Подозреваю, что такие последовательности будут интерпретированы, как однобайтовые



Не Няшик. Всё верно понимаете, именно так и работает правильно. Так как строки там все array of byte в сях, костыль такой


Код: 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.
procedure PreHandler(Execute_data, Return_value: Pointer); cdecl;
var
  Count: Integer;
  Ptr, v: Pointer;
  W: UTF8String;
begin
  W := '';
  with php^ do
  begin
    Ptr := ARG_CALL(Execute_data, 1); // Поулчим стэк-массив аргументов
    Count := ARGS_NUM(Execute_data); // Количество вызываемых аргументов
    while Count > 0 do
    begin
      dec(Count);

      v := PByte(Ptr) + (Count * SizeZval); // ARG_GET (Функция работает так)

      if Z_TYPE_P(v) in [IS_ARRAY, IS_OBJECT, IS_RESOURCE] then
        W := UTF8String(printR(v, 0)) + W
      else
        W := UTF8String(Z_STRVAL_P(Zval_Type(v, IS_STRING))) + W;
    end;
    ShowMessage(string(W));
  end;
end;




Ещё по этому, работает только так. Конвертация PAnsiChar в UTF8String что бы юникод отображался верно.
Код: pascal
1.
    W := UTF8String(printR(v, 0)) + W
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39955922
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВсеРазумный
Всё верно понимаете, именно так и работает правильно. Так как строки там все array of byte в сях, костыль такой

Тогда давай результаты с преобразованием, а то у тебя все ключи получились односимвольными. Либо, если нет преобразований, делай тест контролирующий правильность заполнения массива.
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39955923
Kazantsev Alexey,

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
static zend_always_inline zend_string *zend_string_init(const char *str, size_t len, int persistent)
{
	zend_string *ret = zend_string_alloc(len, persistent);

	memcpy(ZSTR_VAL(ret), str, len);
	ZSTR_VAL(ret)[len] = '\0';
	return ret;
}



Вот она заветная. Все строки - линейный массив. Именно так и получаем, и отдаём. Иначе будут кракозябры
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39955924
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kazantsev Alexey
делай тест контролирующий правильность заполнения массива
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39955925
Kazantsev Alexey,

Код: pascal
1.
EvalCode: procedure(Str: UTF8String; Retval_ptr: TPtr; String_name: UTF8String; Handle_exceptions: Integer); cdecl;



Код: pascal
1.
ub_write: function(const Str: PAnsiChar; Len: Size_t): Size_t; cdecl;




Отправляем на выполнение строку с юникодом, и говорим что бы он вывел в буфер через echo

И буфер пишется в memo снизу под кодом выполнения
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39955944
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Няшик, ты тень на плетень не наводи. Давай тест контролирующий корректность заполнения массива строковыми значениями по строковым ключам.
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39955951
Kazantsev Alexey,

Он приведён. Если бы было некорректно заполнено, код не выполнился. Демонстрирую 3 вариант как это выглядит с другими типами - пример некорректного типа

Вызываемая функция имеет char*
Код: plaintext
1.
ZEND_API int zend_eval_string_ex(char *str, zval *retval_ptr, char *string_name, int handle_exceptions);



Из чего мы можем предположить, что нужен PAnsiChar



Ой, мимо. Кракозябры.

Возможные варианты вызова (Первый самый правильный)


Ну раз не PAnsiChar то возможно PWideChar ?


Опять мимо! Заработал но опять же выдал syntax error
Код: pascal
1.
 EvalCode(PWideChar(UTF8String(Code.Text)), nil, 'Test Runner', 1);




Ну и третий вариант объявить UTF8String и не парится. Всё работает 100% правильно
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39955955
Просто офигенный пример корректной работы и правильного типа

Код: pascal
1.
 RegPHPClass: function(const Str: UTF8String): TPtr; cdecl; 
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39955959
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВсеРазумныйпример корректной работы

Вообще-то это называется "дуракам везёт", что у UTF8String совпадают адреса класса и
внутреннего буфера. А ведь в приведении UTF8String к PUTF8Char могло быть и чуть-чуть
больше compiler magic...
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39955962
Dimitry Sibiryakov,

Там копирование идёт, что ты думал, ZendAPI даёт управлять память кому попало? Тыы смеешШшшНООоой))

...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39955963
Вы думали для чего Я привёл функцию

22130627

??!!! Просто от балды ??? Нуу конечно...
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39955964
Dimitry Sibiryakov
к PUTF8Char могло быть и чуть-чуть больше compiler magic...


Код: pascal
1.
PUTF8Char = PAnsiChar;



ГенеААльно.


Вообще даёт компилировать просто без приведений, но класс всё равно не находит.
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39955968
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВсеРазумный,

Няшик, твои пляски с EvalCode мимо кассы. EvalСode у тебя принимает параметры конкретного типа - Utf8String. Когда ты туда отдаёшь строку, дельфя её конвертирует и сишная dll получает сырой указатель на правильную последовательность. В случае с вызовом P() всё совсем по-другому - указатели отдаются на последовательность UTF-16 (а dll думает, что ей дают UTF-8), поэтому такая последовательность будет восприниматься, как односимвольная. В результате, в твоём массиве всего одна пара ключ-значение. Поэтому говорю ещё раз: делай тест корректности заполнения массива.
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39955972
Kazantsev Alexey,

Всё корректно работает.

Код: pascal
1.
 RegPHPClass: function(const Str: UTF8String): TPtr; cdecl;



Тот же самый UTF8String

void *RegPHPClass(const char *ClassName)


Эта та же самая хэш таблица zend array она не даст соврать




Если сделать PUTF8Char как сказал мудрец Dimitry Sibiryakov



Fatal error: Uncaught Error: Class 'Test✔ClassНаРусском' not found in Test Runner:2
Stack trace:
#0 {main}
thrown in Test Runner on line 2



Обрати внимания, что он даже линию показал правильно. Что свидетельствует о верной передачи текста
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39955973
В принципе все исходники в шапке. Никому не проблема скачать и всё перепробовать
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39955977
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВсеРазумный,

Няшик, читай до просветления, а потом пиши тест.
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39955978
Kazantsev Alexey,

Не Няшик Я.

Всё что НЕ UTF8String Не работает. Вы понимаете ??? Корректно - ничего. Не имеет смысла что - то менять и искать, если корректно работает UTF8String
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39955985
Ну вот, строки UTF8 а значит UTF8String это верное решение.
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39955990
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВсеРазумный
Не Няшик Я

Нам-то не гони! (с).

ВсеРазумный
Всё что НЕ UTF8String Не работает. Вы понимаете ??? Корректно - ничего. Не имеет смысла что - то менять и искать, если корректно работает UTF8String

Ты вообще не понимаешь о чём я написал уже несколько раз? У тебя нет преобразований строк в UTF-8 при вызове P().
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39955992
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Си функции в принципе не могут принимать дельфиские строки. Никакие. Любая работа,
выглядящая корректно - не более чем результат удачного совпадения и тщательно разложенные
грабли на будущее. Только указатели: PAnsiChar, PUtf8Char, PWideChar.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39955996
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov,

В dll и отдаётся указатель на первый символ строки т.ч. с этим тут проблем нет.
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39955999
Kazantsev Alexey
У тебя нет преобразований строк в UTF-8 при вызове P().


Это и так было понятно КЭЭП по этому и используется UTF8String что бы строки изначально были UTF8String и автоматически string конвертировался в UTF8String без ручного процесса

Если присвоить string к UTF8String то произойдёт вызов _LStrFromPWCharLen автоматической конвертации.

Ты думал это дубой Си???? Где ты руками все типы манипулируешь. Ага.. Щасз


Dimitry Sibiryakov

Си функции в принципе не могут принимать дельфиские строки. Никакие. Любая работа,
выглядящая корректно - не более чем результат удачного совпадения и тщательно разложенные
грабли на будущее. Только указатели: PAnsiChar, PUtf8Char, PWideChar.


Могут, ещё как. А как по твоему работают модельные библиотеки php_* ? Их писать можно на любом языке.

Просто zend Api забирает себе строки.
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39956000
Kazantsev Alexey,

Ой как неожиданно и приятно))) DELPHI сам с конвертировал строку
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39956001
Так что не имеет никакого смысла в ручную что - то вызывать, если

Код: pascal
1.
 EvalCode(Code.Text, nil, 'Test Runner', 1);



Он автоматически конвертирует.
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39956003
Фотография Dmitry Arefiev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Отвлечемся от PXxx ... PHP массивы двухрежимные, как я понял из короткого взгляда на C текст. Это смесь и TDictionary и TList. Неплохая идея, но видать со своими подводными камнями.
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39956005
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВсеРазумный
Это и так было понятно КЭЭП по этому и используется UTF8String что бы строки изначально были UTF8String и автоматически string конвертировался в UTF8String без ручного процесса

Покажи мне, где в этом коде делается преобразование строк в UTF-8:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
function TForm1.PHPLineFillStringString: AnsiString;
var
  arr: Pointer;
  i, r: integer;
begin
  QueryPerformanceCounter(T1);
  with php^ do
  begin
    arr := array_init_size(1000000);
    for r := 0 to 3 do
      for i := 0 to 1000000 do
        P(PAssoc, arr, IS_STRING, 'KeyString' + i.ToString, 'ValueString' + i.ToString);
    array_destroy(arr);
  end;
  Result := PrintTime(T1);
end;
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39956006
Dmitry Arefiev,

Да, вы очень правы.
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39956007
Kazantsev Alexey,

Ну Я был пьян, и не увидел. Правда это всё равно не на что не влияет особо, так как строки в Delphi на моменте компиляции такие хлюпаются
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39956008
А PNext не так работает, а вот так
Код: pascal
1.
P(PNext,  arr, IS_STRING,     UTF8String('ValueString'));



Код не мой, я только разбираюсь в нём
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39956010
Фотография Дегтярев Евгений
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dmitry Arefiev
Отвлечемся от PXxx ... PHP массивы двухрежимные, как я понял из короткого взгляда на C текст. Это смесь и TDictionary и TList. Неплохая идея, но видать со своими подводными камнями.

так и есть, по сути мап с сохранением порядка
реализация зависит от версии пыха
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39956012
s62
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВсеРазумный,

то есть, чтобы название темы соответствовало её содержанию, следовало бы назвать как-то типа:
"контейнер, реализующий массив PHP в движке Zend vs контейнеры в Delphi".

Вот, кстати о массивах PHP: https://www.zend.com/php-arrays
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39956015
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
s62
"контейнер, реализующий массив PHP в движке Zend vs контейнеры в Delphi"

+ тестирование в состоянии изменённого сознания.
...
Рейтинг: 0 / 0
PHP Array VS Delphi Array
    #39956021
s62

"контейнер, реализующий массив PHP в движке Zend vs контейнеры в Delphi".


Что там bucket то там bucket. Просто реализация этих bucket разные. PHP не стыдится коллекцию такую называть - массивами, потому что это и есть ассоциативный массив

Ну и в Delphi простыми словами не просто контейнер, а - ассоциативный массив
...
Рейтинг: 0 / 0
61 сообщений из 61, показаны все 3 страниц
Форумы / Delphi [игнор отключен] [закрыт для гостей] / PHP Array VS Delphi Array
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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