Модераторы: Snowy, MetalFan, bems, Poseidon
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Процедуры с одним именем (OVERLOAD). 
:(
    Опции темы
Robus
Дата 26.6.2009, 08:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Entire



Профиль
Группа: Участник
Сообщений: 32
Регистрация: 15.12.2005

Репутация: 1
Всего: 1



   Хотел оптимизировать свой код. В проекте есть множество мест, где в процедуры передаются стринги. В процессе исполнения кода, каждая така процедура вызывает копирование стринга в стек, что соответственно отбирает время процессора.
Например:
Код

PROCEDURE __Win(S:STRING;XP,YP:DWORD); OVERLOAD;
BEGIN
          PutWin(XP,YP)
          PRINT(S);
END;
BEGIN
    __Win('Menu:',10,10);
END.

В данном случае вызов процедуры "__Win('Menu:',10,10)" создаст в стеке стринг, который в свою очередь при вызове "PRINT(S)" скопируется в новый стек. Я точно знаю, что процедуры "__Win" и "PRINT" никогда не модифицируют стринг, и что можно было бы описать в процедурах стринг как VAR. Но тогда я не смогу так просто делать вызов "__Win('Menu:',10,10)", и мне придётся входящий стринг описывать как отделную переменную. Поэтому я решил сделать две процедуры с одни именем, в одной из которых будет входить стринг как VAR, а в другой как локальная переменная.
Например:
Код

PROCEDURE W_WinRes(VAR S:STRING); OVERLOAD;
BEGIN
...
END;
PROCEDURE W_WinRes(S:STRING); OVERLOAD;
BEGIN
...
END;


Однако компилятору это не понравилось. Как можно решить эту проблему ? Я понимаю, что можно создать процедуры с разными названиями, но это будет не красиво. Хотелось бы красивое решение !
PM MAIL   Вверх
dvamaster
Дата 26.6.2009, 10:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 559
Регистрация: 30.6.2004
Где: Россия : Курган

Репутация: нет
Всего: 10



В таком случае предавай PChar

Код

PROCEDURE __Win(S:PChar;XP,YP:DWORD); OVERLOAD;
...
var
  s: String;
...
__Win(PChars(s), 10, 10);


но лучше

Код

var
  s: array [0..1023] of Char;
...
__Win(@s, 10, 10);



--------------------
Хорошую информацию трудно добыть. Сделать с ней что-нибудь - еще труднее. /L. Skywalker/

Что же я сделал не так? /Король Лир/

Я делаю это для твоего же блага! /Любой родитель и палач/

PKUNZIP.ZIP /неизвестный/
PM MAIL WWW ICQ   Вверх
Robus
  Дата 26.6.2009, 10:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Entire



Профиль
Группа: Участник
Сообщений: 32
Регистрация: 15.12.2005

Репутация: 1
Всего: 1



Цитата(dvamaster @  26.6.2009,  10:22 Найти цитируемый пост)
В таком случае предавай PChar

С PChar есть ньюансы ...
1. У меня в коде большое количество фиксированных процедур без внешних стрингов, то есть запись непосредственно __Win('Menu:',10,10); !!! Но самое интересное, что почему-то PCHAR позволяет при компиляции не создавать внешни стринг, а PSTRING ругается. Не понятно !!!
2. У меня часто в стринг передаются параметры, например __Win(#22#0#0#14#7'Menu:',10,10); где 22 код координат и два числа и 14 код цвета. А PCHAR обрубает до нолика. Всё же классический стринг паскаля мне нравится больше. Но если не найду решение проблемы, то скорее всего перейду на PCHAR.

В любом случае спасибо за помощь, жду ещё предложений ...
PM MAIL   Вверх
dvamaster
Дата 26.6.2009, 11:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 559
Регистрация: 30.6.2004
Где: Россия : Курган

Репутация: нет
Всего: 10



PChar является встроеным типом, для него много встроенных конверторов, в частности

PChar(строковая переменная)
PChar('Какой-то текст')

здесь в обоих случаях используется String который преобразуется в PChar встроенными методами

так как на выходе получаем указатель на ANSI-строку, то она имеет длину до первого символа #0
для передачи строки с символом #0 это не годится

PString - не является встроенным типом для компилятора, по этому нельзя вызвать процедуру так
Код

__Win('текст', 10, 10);


выход
Код

var
  t: String;
...
t := 'текст';
__Win(@t, 10, 10);



--------------------
Хорошую информацию трудно добыть. Сделать с ней что-нибудь - еще труднее. /L. Skywalker/

Что же я сделал не так? /Король Лир/

Я делаю это для твоего же блага! /Любой родитель и палач/

PKUNZIP.ZIP /неизвестный/
PM MAIL WWW ICQ   Вверх
CodeMonkey
Дата 26.6.2009, 11:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1839
Регистрация: 24.6.2008
Где: Россия, Тверь

Репутация: 29
Всего: 89



Код
procedure __Win(const S: String; XP,YP: DWord);
begin
  PutWin(XP,YP)
  Print(S);
end;

begin
    __Win('Menu:',10,10);
end.



--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
1000000dollars
Дата 26.6.2009, 11:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 231
Регистрация: 6.10.2007

Репутация: нет
Всего: 8



Я решил провести следственный эксперимент:

Код

PROGRAM strings2;
{$APPTYPE CONSOLE}

USES
 SysUtils;

TYPE
 DWORD = Cardinal;
 
VAR
 _sp: Cardinal;

PROCEDURE PutWin(XP,YP: DWORD);
           BEGIN
            asm
             mov _sp, ESP // получаем адрес указателя стека
            end;
            WriteLn ('Stack Pointer: 0x',IntToHex(_sp,8));

            WriteLn (IntToStr(XP), 'x',IntToStr(YP));
           END;
PROCEDURE PRINT(S: String);
           BEGIN
            asm
             mov _sp, ESP // получаем адрес указателя стека
            end;
            WriteLn ('Stack Pointer: 0x',IntToHex(_sp,8));

            Writeln (S);
           END;

PROCEDURE __Win(S:STRING;XP,YP:DWORD); OVERLOAD;
           BEGIN
            asm
             mov _sp, ESP // получаем адрес указателя стека
            end;
            WriteLn ('Stack Pointer: 0x',IntToHex(_sp,8));

            PutWin(XP,YP);
            PRINT(S);
           END;

BEGIN
 asm
  mov _sp, ESP // получаем адрес указателя стека
 end;
 WriteLn ('Stack Pointer: 0x',IntToHex(_sp,8));

 WriteLn;

// если строка копируется, то выводы выделенной памяти и указателя стека должны быть разными
 __Win ('Menu', 10, 10);
 WriteLn;
 __Win ('Menu111111111111111111111111111111111111111111111111111111111111111111', 10, 10);

 WriteLn;
 WriteLn ('Done.');
 ReadLn;
END.


Результат получился следующий:
Код

Stack Pointer: 0x0013FFA4

Stack Pointer: 0x0013FF80
Stack Pointer: 0x0013FF58
10x10
Stack Pointer: 0x0013FF64
Menu

Stack Pointer: 0x0013FF80
Stack Pointer: 0x0013FF58
10x10
Stack Pointer: 0x0013FF64
Menu111111111111111111111111111111111111111111111111111111111111111111

Done.


В первой группе вызовов (с короткой строкой) стек колеблется от 0x0013FF80 до 0x0013FF64.
Во второй группе вызовов (с длинной строкой) стек колеблется от 0x0013FF80 до 0x0013FF64.
Вывод: строка в стек не копируется.

В стек передаётся адрес строки (указатель на строку). Кроме того Delphi умно работает со строками, поэтому содержимое строк копируется только в случае необходимости. Пример:

Код

PROGRAM strings3;
{$APPTYPE CONSOLE}
USES
 SysUtils;

VAR
 S1,
 S2 : String;

BEGIN
 WriteLn ('Allocated memory ', AllocMemSize);
 S1:= 'test';
 WriteLn ('Allocated memory ', AllocMemSize);
 S2:= S1;
 WriteLn ('Allocated memory ', AllocMemSize);
 S2[3] := 'x';
 WriteLn ('Allocated memory ', AllocMemSize);

 WriteLn ('Done.');
 ReadLn;
END.


Вывод:
Код

Allocated memory 1716 - было выделено изначально
Allocated memory 1732 - после инициализации S1
Allocated memory 1732 - после присваивания S2:=S1 // копирования данных не произошло!
Allocated memory 1748 - после изменения S2 // копирование исходной строки произошло тут.
Done.



PM MAIL   Вверх
CodeMonkey
Дата 26.6.2009, 12:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1839
Регистрация: 24.6.2008
Где: Россия, Тверь

Репутация: 29
Всего: 89





--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
Robus
Дата 26.6.2009, 16:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Entire



Профиль
Группа: Участник
Сообщений: 32
Регистрация: 15.12.2005

Репутация: 1
Всего: 1



Да ... Точно ... Стринг не копируется ... Мало того, я перевёл всё в PCHAR, и результат стал на много хуже !!! Было 135 фпс, а стало 102 !!!

Нужно изучть более детально это ... Наверное зря я поднял этот вопрос, только форум засорил ...
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Для новичков"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.1974 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.