powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Длинные варчары как парметры
49 сообщений из 49, показаны все 2 страниц
Длинные варчары как парметры
    #39066566
Polesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Привет всем.

Заранее прошу прощения за многабукаф.

Имеется некий программный источник, последовательно выдающий значения типа INTEGER (в принципе, аналог датасета). Серия данных составляет около 500000 значений, среди которых 50000 (около 10%) уникальных, т.е. в серии данных имеются повторяющиеся значения. Требуется из поступающей серии сохранить в БД уникальные значения.

Что имеем: FB 2.5.4, Delphi, FIBPlus

В тестовой БД реализована таблица для хранения значений:
Код: plsql
1.
2.
3.
CREATE TABLE IDS (
    ID  INTEGER NOT NULL PRIMARY KEY
);



Все нижеописанные способы производились на одном и том же локальном компьютере, каждый вариант выполнялся по три раза, БД каждый раз пересоздавалась из скрипта. Каждая серия состояла из 500000 значений, среди которых 10% (50000) уникальных.

1.
В БД реализована хранимая процедура для ввода значений:
Код: plsql
1.
2.
3.
4.
5.
6.
CREATE PROCEDURE INSERT_IDS( ID INTEGER )
AS
BEGIN
  IF ( NOT EXISTS( SELECT * FROM IDS WHERE ID = :ID ) ) THEN
    INSERT INTO IDS( ID ) VALUES( :ID );
END



В клиентской программе серия данных эмулировалась следующим кодом:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
  pFIBQuery1.Text := 'execute procedure INSERT_IDS( :ID )';
  pFIBQuery1.Transaction.StartTransaction;
  for i := 1 to 500000 do
  begin
    pFIBQuery1.Params[0].AsInteger := Random( 50000 );
    pFIBQuery1.ExecQuery;
  end;
  pFIBQuery1.Transaction.Commit;




Среднее время обработки серии составило примерно 320 секунд.

После чего в теле хранимой процедуры был оставлен только EXIT, т.е. процедура вообще ничего не делала. Среднее время обработки серии составило примерно 140 секунд. Для 500000-кратного вызова пустой процедуры потребовалось 180 секунд.

2.
С целью сокращения времени обработки серии было решено уменьшить количество вызовов хранимой процедуры посредством передачи в SP множества значений в виде строки с разделителем вида '12~1~4~123~'. Для парсинга передаваемой строки была реализована некая UDF, являющейся по сути однопроходным сканером переданной строки.
Код: plsql
1.
2.
3.
4.
5.
DECLARE EXTERNAL FUNCTION SCAN_IDS
    CSTRING(32765),
    INTEGER
RETURNS INTEGER BY VALUE
ENTRY_POINT 'ScanIds' MODULE_NAME 'Ids.dll';



Хранимая процедура был изменена:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
CREATE PROCEDURE INSERT_IDS ( STR VARCHAR(32765) )
AS
  DECLARE VARIABLE POS INTEGER;  -- позиция сканирования строки
  DECLARE VARIABLE CNT INTEGER;  -- количество символов значение от позиции
  DECLARE VARIABLE VAL INTEGER;  -- целочисленное значение в позиции сканирования
BEGIN
  POS = 1;
  WHILE ( 1 = 1 ) DO
  BEGIN
    CNT = SCAN_IDS( :STR, :POS );
    IF ( CNT = 0 ) THEN   BREAK;

    VAL = CAST( SUBSTRING( :STR FROM :POS FOR :CNT ) AS INTEGER );
    IF ( NOT EXISTS( SELECT * FROM IDS WHERE ID = :VAL ) ) THEN
      INSERT INTO IDS( ID ) VALUES( :VAL );
    POS = :POS + :CNT + 1;
  END
END



Код в клиентском приложении тоже изменился:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
  pFIBQuery1.Text := 'execute procedure INSERT_IDS( :ID )';
  pFIBQuery1.Transaction.StartTransaction;
  s := '';
  for i := 1 to 500000 do
  begin
    s := s + IntToStr( Random( 50000 ) ) + '~';
    if Length( s ) > 32750 then
    begin
      pFIBQuery1.Params[0].AsString := s;
      pFIBQuery1.ExecQuery;
      s := '';
    end;
  end;
  if s <> '' then
  begin
    pFIBQuery1.Params[0].AsString := s;
    pFIBQuery1.ExecQuery;
  end;
  pFIBQuery1.Transaction.Commit;


Среднее время обработки серии составило примерно 110 секунд (почти в 3 раза быстрее по сравнению с первым вариантом).

3.
Было изменено объявление UDF: параметр CSTRING(32765) был объявлен, как CSTRING(16384), соответственно в хранимой процедуре параметр был изменен на VARCHAR(16384), в клиентской программе контроль максимальной длины был уменьшен до 16370. Среднее время обработки серии составило примерно 42 секунды.

Собственно, вопрос: почему 3-й вариант быстрее 2-го в 2.5 раза, хотя варианты отличаются только объявлением максимально возможной длины строки (32765 во 2-м варианте и 16384 в 3-м). Неужели выделение памяти объемом 16K производится гораздо быстрее, нежели чем выделение памяти объемом 32K?

С уважением, Polesov.
...
Рейтинг: 0 / 0
Длинные варчары как парметры
    #39066567
Polesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Извиняюсь, попутал
После чего в теле хранимой процедуры был оставлен только EXIT, т.е. процедура вообще ничего не делала. Среднее время обработки серии составило примерно 140 секунд. Для 500000-кратного вызова пустой процедуры потребовалось 180 секунд.

После чего в теле хранимой процедуры был оставлен только EXIT, т.е. процедура вообще ничего не делала. Среднее время обработки серии составило примерно 180 секунд, т.е. это время потребовалось для 500000-кратного вызова пустой процедуры. 140 секунд потребовалось для проверки 500000 и вставки 50000 значений.
...
Рейтинг: 0 / 0
Длинные варчары как парметры
    #39066653
Фотография Tonal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Внешние таблицы не пробовал?
...
Рейтинг: 0 / 0
Длинные варчары как парметры
    #39066700
Шавлюк Евгений
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Polesov,

А если вместо варчара текстовый блоб?
...
Рейтинг: 0 / 0
Длинные варчары как парметры
    #39066709
Шавлюк Евгений
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Polesov,

Я бы сделал еще сделал insert во временную таблицу а потом insert into .. select .. from tmp group by
...
Рейтинг: 0 / 0
Длинные варчары как парметры
    #39066729
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Polesov3.
Было изменено объявление UDF: параметр CSTRING(32765) был объявлен, как CSTRING(16384), соответственно в хранимой процедуре параметр был изменен на VARCHAR(16384), в клиентской программе контроль максимальной длины был уменьшен до 16370. Среднее время обработки серии составило примерно 42 секунды.

Собственно, вопрос: почему 3-й вариант быстрее 2-го в 2.5 раза, хотя варианты отличаются только объявлением максимально возможной длины строки (32765 во 2-м варианте и 16384 в 3-м). Неужели выделение памяти объемом 16K производится гораздо быстрее, нежели чем выделение памяти объемом 32K?Очевидно - да. Попробуй строку в 28-30К, если интересно
...
Рейтинг: 0 / 0
Длинные варчары как парметры
    #39066867
Polesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hvlad, дело оказалось не в размере выделяемой памяти, а в длине передаваемой строки. Чуть позже выложу результаты.

To All: вопрос не в том, как сделать быстрее, а почему такая разница по времени выполнения при различных длинах передаваемого параметра.

С уважением, Polesov.
...
Рейтинг: 0 / 0
Длинные варчары как парметры
    #39066872
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Шавлюк ЕвгенийЯ бы сделал еще сделал insert во временную таблицу

А я бы сделал отсечение дубликатов ещё в приложении, без обращения к серверу вообще.
Уверен, этот вариант выйграет по скорости со значительным отрывом.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Длинные варчары как парметры
    #39066899
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PolesovTo All: вопрос не в том, как сделать быстрее, а почему такая разница по
времени выполнения при различных длинах передаваемого параметра.
Из-за того, что у тебя stateless алгоритм в UDF и его сложность O(N^2/2).
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Длинные варчары как парметры
    #39066910
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovPolesovTo All: вопрос не в том, как сделать быстрее, а почему такая разница по
времени выполнения при различных длинах передаваемого параметра.
Из-за того, что у тебя stateless алгоритм в UDF и его сложность O(N^2/2).С чего бы это ? Там POS передаётся в UDF
...
Рейтинг: 0 / 0
Длинные варчары как парметры
    #39066955
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hvladС чего бы это ? Там POS передаётся в UDF
Хммм... Действительно. Был неправ.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Длинные варчары как парметры
    #39067020
Polesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovИз-за того, что у тебя stateless алгоритм в UDF и его сложность O(N^2/2).


Нет. Вот текст UDF:
Код: 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.
library Ids;

{
DECLARE EXTERNAL FUNCTION SCAN_IDS
    CSTRING(32765),
    INTEGER
RETURNS INTEGER BY VALUE
ENTRY_POINT 'ScanIds' MODULE_NAME 'Ids.dll';
}
function ScanIds( Value : pAnsiChar; var Index : integer ) : integer; cdecl; export; assembler;
asm
    Add   ESP, -$08

    Mov   EDX, EDI
    Mov   EDI, [EBP + $08]    // EDI = Value

    Mov   ECX, [EBP + $0C]
    Mov   ECX, [ECX]          // ECX = Index
    Dec   ECX                 // Index не с 1, а с 0
    Add   EDI, ECX

    Xor   EAX, EAX
    Cmp   Byte Ptr [EDI], AL  // Проверка на конец CSRING
    Jz    @@1

    Mov   ECX, 00007FFDh      // масимально возможная длина VARCHAR
    Mov   EBX, ECX            // Запоминаем позицию начала поиска тильды
    Dec   EBX
    Mov   AL,  '~'
    Repne Scasb
    Mov   EAX, EBX
    Sub   EAX, ECX

@@1:
    Mov   EDI, EDX
    Pop   ECX
    Pop   ECX
end;

exports
  ScanIds;

end.
...
Рейтинг: 0 / 0
Длинные варчары как парметры
    #39067033
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PolesovНет.
Действительно нет. Стало быть проблема действительно может быть в коде птицы. Возможно,
она в избыточном преобразовании чарсетов при формировании параметра.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Длинные варчары как парметры
    #39067037
fb user
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Шавлюк ЕвгенийЯ бы сделал еще сделал insert во временную таблицу а потом insert into .. select .. from tmp group by
Аналогично. Но вместо временной таблицы использовал бы хранимку, для скорости.
...
Рейтинг: 0 / 0
Длинные варчары как парметры
    #39067048
Polesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть 3 места, где определяется максимально возможная длина строки:

- объявление UDF
- объявление входящего параметра SP
- клиентское приложение, формирующее строку

Провел несколько тестов. Каждый тест проводился 3 раза, перед каждым проведением БД пересоздавалась из скрипта.
В UDF и SP длина параметра была объявлена 32765, только в клиентском приложении менялась максимально допустимая длина строки.
Вот что получилось (другой компьютер, другая ОС, FB 2.5.4):

Max len: 32750 - 28.9 сек
Max len: 16370 - 24.6 сек
Max len: 8180 - 21.4 сек
Max len: 4080 - 20.2 сек
Max len: 2040 - 20.0 сек
Max len: 1020 - 20.0 сек

Видно, что время обработки серии зависит от длины передаваемой строки (в случае с 32К и 2К почти в 1.5 раза).

Any cojmments?

С уважением, Polesov.
...
Рейтинг: 0 / 0
Длинные варчары как парметры
    #39067050
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fb user,

в трёшке можно попробовать написать внешнюю хранимую процедуру для разделения значения. Думаю она могла бы работать гораздо быстрее.
...
Рейтинг: 0 / 0
Длинные варчары как парметры
    #39067077
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PolesovAny cojmments?
непонятно, что тут комментировать. длиннее строка, медленнее выполнение.
...
Рейтинг: 0 / 0
Длинные варчары как парметры
    #39067124
WildSery
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денис,

У автора вопрос не с разбором строки.
...
Рейтинг: 0 / 0
Длинные варчары как парметры
    #39067127
Polesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kdv, суммарная длина строк одинакова во всех случаях.
...
Рейтинг: 0 / 0
Длинные варчары как парметры
    #39067152
afgm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денисв трёшке можно попробовать написать внешнюю хранимую процедуру для разделения значения. Думаю она могла бы работать гораздо быстрее.
В своё время была идея написать сплит и для 2.5 через несколько функций
handle = split_begin(blob, delimiter);
value = split_get_next(handle);
split_free(handle);
Такой подход череват, но не всегда есть возможность внешнюю таблицу генерить для скорости.
Я вот не плюсист, и жду когда умеющие напишут split для 3.0. Хотя есть мнение, что было бы неплохо сделать стандартной, для оптимизации по передаваемым типам данных и синтаксису. Но и внешняя вполне сгодилась бы.
Вот у меня в базе приходится часто резать данные. Можно из вне толкать нарезку колбасы, но тогда получается дофига вставок, что опять выходит боком. Тему "а вот в слонике сделано..." тут не любят, но недавние тесты показали, что split там получается реально быстрым. FB-PSQL и MSSQL (2 реализации XML и CLR-процедура, с чистым substring на T-SQL совсем плохо) на порядок медленнее (буквально). И что радует, что PSQL в прице, даже не смотря на умеренно порождение временных блобов (сначала пилим блоб на varchar(32000), а потом пилим строки) дал результат сравнимый по скорости с CLR в MSSQL Что по-своему радует
...
Рейтинг: 0 / 0
Длинные варчары как парметры
    #39067193
Polesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovСтало быть проблема действительно может быть в коде птицы. Возможно,
она в избыточном преобразовании чарсетов при формировании параметра.


Вот это вполне может быть.
Провел несколько тестов для различных CHARACTER SET при длине параметра 32К.
Строка объявления параметра SP:
Код: plsql
1.
CREATE PROCEDURE INSERT_IDS ( STR VARCHAR(32765) CHARACTER SET NONE )



Character set NONE - 48.4 сек
Character set ASCII - 64.2 сек
Character set WIN1251 - 28.4 сек

Остается открытым вопрос, почему при одинаковых CHARACTER SET при 32К и 4К время обработки отличается почти в 1.5 раза.

С уважением, Polseov.
...
Рейтинг: 0 / 0
Длинные варчары как парметры
    #39067194
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PolesovВидно, что время обработки серии зависит от длины передаваемой строки
я комментирую то, что вы пишете. Не вижу вопроса в скорости в зависимости от длины строки.
...
Рейтинг: 0 / 0
Длинные варчары как парметры
    #39067201
Polesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kdv, во всех случаях одинаковый суммарный объем передается кусками разной длины. От размера передаваемого куска зависит суммарное время обработки всего объема.
...
Рейтинг: 0 / 0
Длинные варчары как парметры
    #39067215
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
afgm,

я давно хотел попробовать написать UDR preg_split, но времени не хватает. 3.0 мы пока не используем в разработке, только тестируем на совместимость и прицениваемся к новым фичам. Как выйдет RC уже будем полномасштабно готовится к переезду.
...
Рейтинг: 0 / 0
Длинные варчары как парметры
    #39067228
afgm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денис,

Думаю нужно 2 версии, либо параметр. Версия для обычных строк сильно быстрее.
...
Рейтинг: 0 / 0
Длинные варчары как парметры
    #39069223
Polesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Up.


Несколько изменил условия тестов:

UDF стала обычной пустышкой:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
function DummyInt( Value : pAnsiChar; var Index : integer ) : integer; cdecl; export;
begin
  Result := 0;
end;

exports
  DummyInt;



Объявление параметра UDF максимальной длины:
Код: plsql
1.
2.
3.
4.
5.
DECLARE EXTERNAL FUNCTION DUMMY_INT
    CSTRING(32765),
    INTEGER
RETURNS INTEGER BY VALUE
ENTRY_POINT 'DummyInt' MODULE_NAME 'Ids.dll';




Параметр хранимой процедуры тоже максимальной длины:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
CREATE PROCEDURE INSERT_IDS ( STR VARCHAR(32765) )
AS
  DECLARE VARIABLE CNT INTEGER;
BEGIN
  WHILE ( 1 = 1 ) DO
  BEGIN
    CNT = DUMMY_INT( :STR, :POS );
    IF ( CNT = 0 ) THEN   BREAK;
  END
END



В клиентском приложении все без изменений (s имеет тип AnsiString):
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
  pFIBQuery1.SQL.Text := 'execute procedure INSERT_IDS( :ID )';
  s := '';
  pFIBQuery1.Transaction.StartTransaction;
  for i := 1 to 500000 do
  begin
    s := s + IntToStr( Random( 50000 ) ) + '~';
    if Length( s ) > 32750 then
    begin
      pFIBQuery1.Params[0].AsString := s;
      pFIBQuery1.ExecQuery;
      s := '';
    end;
  end;
  if s <> '' then
  begin
    pFIBQuery1.Params[0].AsString := s;
    pFIBQuery1.ExecQuery;
  end;
  pFIBQuery1.Transaction.Commit;



Тесты проводились с контролем длины передаваемого параметра 32750 и 4080 символов.

Напомню, что каждый тест проводился троекратно. После каждого проведения база пересоздавалась из скрипта.

В первой серии тестов в хранимой процедуре производился вызов UDF DUMMY_INT.
Во второй серии тестов вызов UDF был отключен:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
CREATE PROCEDURE INSERT_IDS ( STR VARCHAR(32765) )
AS
  DECLARE VARIABLE CNT INTEGER;
BEGIN
  WHILE ( 1 = 1 ) DO
  BEGIN
    CNT = 0;    -- DUMMY_INT( :STR, :POS );
    IF ( CNT = 0 ) THEN   BREAK;
  END
END



Вот что получилось:

Длина параметра: 32750
Вызов SP с вызовом UDF: 08.56 сек
Вызов SP без вызова UDF: 08.55 сек

Длина параметра: 4080
Вызов SP с вызовом UDF: 01.25 сек
Вызов SP без вызова UDF: 01.24 сек

Видно, что наличие вызова UDF на время выполнения теста практически не влияет.

Остается предположить, что в коде FB при передаче параметра типа VARCHAR реализован,
как выразился Dimitry Sibiryakov, "stateless алгоритм и его сложность O(N^2/2)".

Вот как-то так...


С уважением, Polesov.
...
Рейтинг: 0 / 0
Длинные варчары как парметры
    #39069238
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Polesovif Length( s ) > 32750 then
Тесты проводились с контролем длины передаваемого параметра 32750 и 4080 символов.
? надеюсь, для теста 4080 символов это условие менялось в коде?
я бы вам советовал провести тест с длиной 7к и 9к, т.е. когда одно значение влезает в один пакет tcp, и не влезает.
...
Рейтинг: 0 / 0
Длинные варчары как парметры
    #39069285
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Polesov,

как измерялось время ?
...
Рейтинг: 0 / 0
Длинные варчары как парметры
    #39069477
Polesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kdv? надеюсь, для теста 4080 символов это условие менялось в коде?
Да, в коде клиентского приложения.

kdvя бы вам советовал провести тест с длиной 7к и 9к, т.е. когда одно значение влезает в один пакет tcp, и не влезает.
Длина параметра: 7000
Вызов SP без вызова UDF: 1.95 сек

Длина параметра: 9000
Вызов SP без вызова UDF: 2.46 сек
...
Рейтинг: 0 / 0
Длинные варчары как парметры
    #39069480
Polesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hvladкак измерялось время ?
В коде клиентского приложения:

Код: 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.
var
  t : TTime;
begin
  t := Time;

  pFIBQuery1.SQL.Text := 'execute procedure INSERT_IDS( :ID )';
  s := '';
  pFIBQuery1.Transaction.StartTransaction;
  for i := 1 to 500000 do
  begin
    s := s + IntToStr( Random( 50000 ) ) + '~';
    if Length( s ) > 9000 then
    begin
      pFIBQuery1.Params[0].AsString := s;
      pFIBQuery1.ExecQuery;
      s := '';
    end;
  end;
  if s <> '' then
  begin
    pFIBQuery1.Params[0].AsString := s;
    pFIBQuery1.ExecQuery;
  end;
  pFIBQuery1.Transaction.Commit;
  t := Time - t;



Время осреднялось по результатам трех тестов.
...
Рейтинг: 0 / 0
Длинные варчары как парметры
    #39069646
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Polesov,

т.е. все расходы на стороне клиента - в общую кучу. Так и надо, ага.
...
Рейтинг: 0 / 0
Длинные варчары как парметры
    #39069704
Polesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hvlad

Думаю, следует исходить из того, что сумма всех расходов на клиенте в неком приближении есть величина постоянная.
По крайней мере, не отличается в 7 раз в зависимости от длины передаваемого параметра.
...
Рейтинг: 0 / 0
Длинные варчары как парметры
    #39069752
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PolesovДумаю, следует исходить из того, что сумма всех расходов на клиенте в неком приближении есть величина постоянная.С чего бы это ?
Ровно то же самое можно сказать о сервере.
...
Рейтинг: 0 / 0
Длинные варчары как парметры
    #39069766
Polesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hvlad

В каждом тесте выполняется цикл
Код: pascal
1.
  for i := 1 to 500000 do



На каждую итерацию цикла в строке накапливается псевдослучайные значения, разделенные тильдой
Код: pascal
1.
    s := s + IntToStr( Random( 50000 ) ) + '~';



При превышении длины строки некого константного значения
Код: pascal
1.
    if Length( s ) > 32750 then



Передается строковый парамер, вызывается хранимая процедура и строке присваивается значение ''
Код: pascal
1.
2.
3.
      pFIBQuery1.Params[0].AsString := s;
      pFIBQuery1.ExecQuery;
      s := '';



И где здесь может быть разница в 7 раз при изменении константного значения сравнения с 32750 до 4080?
...
Рейтинг: 0 / 0
Длинные варчары как парметры
    #39069804
miwaonline
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Polesov,

Из-за "безразмерных" стрингов в дельфи работа с оными иногда может преподносить сюрпризы в плане скорости или потребления памяти. Я бы тест переделал. Хотя бы для того, чтобы не гадать попусту.
...
Рейтинг: 0 / 0
Длинные варчары как парметры
    #39069811
miwaonline
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PolesovНа каждую итерацию цикла в строке накапливается псевдослучайные значения, разделенные тильдой
...
Передается строковый парамер, вызывается хранимая процедура и строке присваивается значение ''
..
И где здесь может быть разница в 7 раз при изменении константного значения сравнения с 32750 до 4080?

Например, в процитированных моментах.

Вот здесь один умный человек пишет:
Обычно, каждый раз, когда вы присваиваете одну строку другой, компилятору надо бы выделять память и копировать текст из одной переменной в другую. Поскольку строки в Delphi могут быть очень большими (теоретически до 2 Гб максимум в 32-х разрядных приложениях), это может быть весьма медленно.

Резюмируя, - для категорических утверждений тест надо доработь. ИМХО.
...
Рейтинг: 0 / 0
Длинные варчары как парметры
    #39069889
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PolesovДлина параметра: 7000
Вызов SP без вызова UDF: 1.95 сек

Длина параметра: 9000
Вызов SP без вызова UDF: 2.46 сек
ну вот и результат на оверхед при +1 пакете. А с 32750 относительно 4080 получается разница в +3 пакета
...
Рейтинг: 0 / 0
Длинные варчары как парметры
    #39069890
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Polesov,

я так понимаю, что ваши умозаключения сделаны по примеру копирования большого файла блоками - чем больше блок, тем быстрее копируется, и наоборот. Тут это так не работает.
...
Рейтинг: 0 / 0
Длинные варчары как парметры
    #39069892
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Polesov,

можно попробовать в конфиге поменять
TcpRemoteBufferSize = 8192
на 16384, и перепроверить тест с 7к и 9к. Ну и с 4 и 32. А потом проверить на 32768.
...
Рейтинг: 0 / 0
Длинные варчары как парметры
    #39069895
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Polesov,

хост локальный или удалённый?
...
Рейтинг: 0 / 0
Длинные варчары как парметры
    #39069935
Polesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miwaonline, легче всего в текущей реализации теста отключить вызов SP и заменить на передачу полученного стринга через, ну, скажем, сокеты. На днях займусь этим. Впрочем, предлагайте методу - готов рассмотреть возможность переделки теста.
...
Рейтинг: 0 / 0
Длинные варчары как парметры
    #39069936
Polesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miwaonline

Ну, никаких категоричных утверждений с моей стороны не было. Есть желание разобраться. Я уже отписл - предлагайте методу проведения тестов, готов рассмотреть.
...
Рейтинг: 0 / 0
Длинные варчары как парметры
    #39069939
Polesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kdv, переделаю тест на передачу полученной строки через сокеты без вызова SP - там видно будет.
...
Рейтинг: 0 / 0
Длинные варчары как парметры
    #39069941
Polesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kdvя так понимаю, что ваши умозаключения сделаны по примеру копирования большого файла блоками - чем больше блок, тем быстрее копируется, и наоборот.

Нет, на основании тестирования некой UDF WordNum из библиотеки bz_func.dll
...
Рейтинг: 0 / 0
Длинные варчары как парметры
    #39069944
Polesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kdvPolesov,

можно попробовать в конфиге поменять
TcpRemoteBufferSize = 8192
на 16384, и перепроверить тест с 7к и 9к. Ну и с 4 и 32. А потом проверить на 32768.

Хорошо, попробую.
...
Рейтинг: 0 / 0
Длинные варчары как парметры
    #39069946
Polesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денисхост локальный или удалённый?

Пробовал и на локальном, и на удаленном - соотношения результатов примерно одинаковы.
Последнюю серию тестов делал на localhost.
...
Рейтинг: 0 / 0
Длинные варчары как парметры
    #39069951
Polesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kdvну вот и результат на оверхед при +1 пакете. А с 32750 относительно 4080 получается разница в +3 пакета

Следуя этой версии, результаты для длины 9000 и 15000 должны быть примерно одинаковы. Так? Завтра проверю.
...
Рейтинг: 0 / 0
Длинные варчары как парметры
    #39070311
miwaonline
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Polesovmiwaonline

Ну, никаких категоричных утверждений с моей стороны не было. Есть желание разобраться. Я уже отписл - предлагайте методу проведения тестов, готов рассмотреть.
Вообще оптимальным считается воспроизведение бага средствами чистого isql. Так что я бы делал что-то типа такого (пример грубый, просто для общего представления):
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
  s := '';
  pFIBQuery1.Transaction.StartTransaction;
  for i := 1 to 500000 do
  begin
    s := s + IntToStr( Random( 50000 ) ) + '~';
    if Length( s ) > 9000 then
    begin
      StringList1.Items.Add( 'execute procedure INSERT_IDS(' + s + '');');
      s := '';
    end;
  end;
  StringList1.SaveToFile('test.sql');


Тоесть генерировал файл с коммандами (чтобы вручную параметры с длинными строками не набивать) и потом измерял время выполнения test.sql.
...
Рейтинг: 0 / 0
Длинные варчары как парметры
    #39070752
Polesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miwaonlineТоесть генерировал файл с коммандами (чтобы вручную параметры с длинными строками не набивать) и потом измерял время выполнения test.sql.

Так и сделал. Ну, что сказать - посыпаю голову пеплом. Для всех длин параметров время выполнения примерно одинаково. Для более длинных строк время немного меньше, видимо за счет уменьшения количества вызовов SP.

В моих тестах основные потери по времени были при конкатенации строки параметров:
Код: pascal
1.
s := s + IntToStr( Random( 50000 ) ) + '~';

При этом из kernel32 вызывается функция LStrCat.

Вопрос можно считать закрытым.

С уважением, Polesov.
...
Рейтинг: 0 / 0
49 сообщений из 49, показаны все 2 страниц
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Длинные варчары как парметры
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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