powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Informix [игнор отключен] [закрыт для гостей] / оптимизация C UDR
5 сообщений из 5, страница 1 из 1
оптимизация C UDR
    #33767549
falcon111
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Привет!

Роясь на сайте IBMеров, нашел статью посвященную оптимизации работы с памятью C-шной UDR при возврате double precision.

Чтобы не пересказывать своими словами умных людей ;) вот выдержка касательно сути проблемы:
Код: 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.
    * i_fp_setfuncstate() and mi_fp_funcstate() let you store and retrieve user-defined data in the MI_FPARAM structure.
    * The first time a function is called, mi_fp_funcstate() returns NULL, so that is how you tell this is the first time the function has been called.
    * So in Good Code # 2 , line  15  retrieves the pointer using mi_fp_funcstate() and checks on line  16  to see if it is NULL. If it is NULL, this is the first time the function has been called, so line  18  allocates storage and line  24  stores the pointer in the MI_FPARAM using mi_fp_setfuncstate().
    * Line  18  allocates storage PER_COMMAND, which guarantees that the memory won't be freed until it is no longer needed by the query.

Good Code # 2 
 
 1    #include <mi.h> 
 2    #include <math.h> 
 3  
 4   mi_double_precision * 
 5   MyLog10(mi_double_precision *x, MI_FPARAM *fParam) 
 6   { 
 7     mi_double_precision *retval=NULL; 
 8  
 9     if (*x <=  0 ) 
 10    { 
 11      mi_db_error_raise(NULL, MI_EXCEPTION, "Input argument must be > 0!"); 
 12 	 return (mi_double_precision *)NULL;  /* not reached */ 
 13    } 
 14  
 15    retval=(mi_double_precision *) mi_fp_funcstate(fParam); 
 16    if(retval==(mi_double_precision *) NULL) /* First time called */
 17    { 
 18      retval=(mi_double_precision *)mi_dalloc(sizeof(mi_double_precision),PER_COMMAND); 
 19      if(retval==(mi_double_precision *) NULL) 
 20      { 
 21        mi_db_error_raise(NULL, MI_EXCEPTION, "Memory allocation failed!"); 
 22        return (mi_double_precision *)NULL;  /* not reached */
 23      } 
 24      mi_fp_setfuncstate (fParam, (void *) retval); 
 25    } 
 26  
 27    /* math library's log10() returns its result by value */ 
 28    *retval=log10(*x); 
 29    return (retval); 
 30  } 

Тут суть в том, что для возвращаемого double значения память выделяется один раз и потом этот же буфер используется для последующих выполнений функции в запросе. Без этого...
автор
The UDR fires once for each row in a query. So if a query scans a thousand rows, the code in Good Code #1 executes a thousand times....and calls mi_alloc() a thousand times, which starts sounding expensive. Consider a table with 40 million rows, and the allocation costs start sounding prohibitive.

Теперь суть вопроса:

У меня вопрос по возврату mi_lvarchar *
Одна из моих процедур возвращает строку всегда 64 байта длиной, поэтому сама собой напрашивается оптимизация - возвращаемый буфер всегда будет правильной длины. Хочется его зареюзать, как в приведенном примере.

У меня буфер для возвращаемого значение получается так:
mi_lvarchar *rc;
rc=mi_new_var(64); mi_set_varlen(rc, 64);
...туда копируется результат вычислений...
return rc;

Пытался наобум повторить метод как
mi_new_var(64, PER_COMMAND) - компилятор ругается.
Если я пытаюсь сохранять сам указатель rc то при втором вычислении функции запрос падает по ексцепшену.
Пытался играться с mi_switch_mem_duration() - не помогло, все равно падает.

Вопрос: можно ли как-то этот буфер реюзать, чтобы не аллокировать по 64 байта на каждую строку выполнения запроса ?

Спасибо за умные мысли :-)
...
Рейтинг: 0 / 0
оптимизация C UDR
    #33781305
vasilis
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
falcon111...
Вопрос: можно ли как-то этот буфер реюзать, чтобы не аллокировать по 64 байта на каждую строку выполнения запроса ?
Спасибо за умные мысли :-)
Похоже, что умные мысли будут только на специализированных форумах по С, но не на этом, посвященном Informix...
...
Рейтинг: 0 / 0
оптимизация C UDR
    #33784525
falcon111
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Похоже, что на С-шных никто не знает, что такое информикс, а на информиксовых - никто не знает, что такое С ;-(
...
Рейтинг: 0 / 0
оптимизация C UDR
    #33784538
Nikolay Kulikov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А ты автору статьи напиши может ответит. Они любят иногда потрепаться.
...
Рейтинг: 0 / 0
оптимизация C UDR
    #33788431
Ilya Kulagin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
falcon111
Код: plaintext
1.
2.
3.
4.
    * So in Good Code # 2 , line  15  retrieves the pointer using mi_fp_funcstate() and checks on line  16  to see if it is NULL. If it is NULL, this is the first time the function has been called, so line  18  allocates storage and line  24  stores the pointer in the MI_FPARAM using mi_fp_setfuncstate().
    * Line  18  allocates storage PER_COMMAND, which guarantees that the memory won't be freed until it is no longer needed by the query.
 18      retval=(mi_double_precision *)mi_dalloc(sizeof(mi_double_precision),PER_COMMAND); 


mi_new_var(64, PER_COMMAND) - компилятор ругается.



И правильно делает. new_var сам по себе аллоцирует память, и параметр у него один. Если надо аллоцировать память другим способом, то именно этот способ и нужно копировать, например:

rc=(mi_lvarchar *)mi_dalloc(тут поставить размер,PER_COMMAND);

Размер, конечно, лучше не напрямую кодировать, а через 64*sizeof(mi_char) или как-то так (увы, лично я в C ориентируюсь примерно как во французском языке: кое-что знаю, но ничего конкретно). Умные мысли по всему этому поводу лежат внутри $INFORMIXDIR/incl/public/*.h

Эти мысли надо показывать C-шным программистам, чтобы они поняли, что такое информикс. По крайней мере, когда мне понадобилась UDR для интерфейса к crypt(), я так и поступил. Мне помогли, правда, сказав "нам лень и тут всё неоптимально, зато работать будет". Поскольку crypt сам по себе от оптимума обязан быть далёк, я и не парюсь...
...
Рейтинг: 0 / 0
5 сообщений из 5, страница 1 из 1
Форумы / Informix [игнор отключен] [закрыт для гостей] / оптимизация C UDR
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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