powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Длинные варчары как парметры
24 сообщений из 49, страница 2 из 2
Длинные варчары как парметры
    #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
24 сообщений из 49, страница 2 из 2
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Длинные варчары как парметры
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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