Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Удалить подстроку из очень большой строки (больше 2 ГБ ) [D7, WinXP]


Страницы:   1 2 3 4 5 6 7

*Ray* ©   (2007-09-07 18:42:00) 

Здравствуйте, уважаемые мастера! Столкнулся со стандартной вроде бы задачей, но с интересного ракурса. Задача проста: Нужно написать функцию, удаляющую все вхождение подстроки в строке. Но есть одно условие: строка очень большая - около 2 Гб, может и больше, и нужно чтобы функция была максимально оптимизирована. Вот здесь я немного теряюсь.

Я сделал так:
Function Del_Str (longstring, string: string):string;
begin
    while pos(str, longsting)>0 do
          begin
                del(longstring, pos(str, longstring), length(str)) ;
          end;
    result:=longstring;  
end;

Функция работает, но одно даже присваивание result значение longstring займет в памяти 4 Гб, если строка 2 Гб. Не говря уже о других операциях. Надо что-то придумать.

Заранее всем ольшое спасибо за предложенные варианты!


Инс   (2007-09-09 21:17:00) [41]


> Что принципиально ограничивает вас работать со строкой >2-3GB?

Как с целым неразрывным блоком данных - да. Как с типом string - да.


oxffff   (2007-09-09 21:15:00) [42]


> Инс ©   (09.09.07 21:05) [94]
>
> > [93] oxffff ©   (09.09.07 21:04)
>
> О виртуальном. Читай [4]


Anatoly Podgoretsky ©   (09.09.07 20:25) [85]
> oxffff  (09.09.2007 20:15:23)  [83]

>Есть и что они доступны в Дельфи

>string = 2^31
>integer тоже самое, а вся индексация идет через него


Что принципиально ограничивает вас работать со строкой >2-3GB?


Инс   (2007-09-09 21:05:00) [43]


> [93] oxffff ©   (09.09.07 21:04)

О виртуальном. Читай [4]


oxffff   (2007-09-09 21:04:00) [44]


> Инс ©   (09.09.07 20:44) [90]
>
> > [89] oxffff ©   (09.09.07 20:43)
>
> И что?


> Anatoly Podgoretsky ©   (09.09.07 20:56) [92]
> > Инс  (09.09.2007 20:44:30)  [90]
>
> Тот же вопрос хотел бы задать.


Читаем Инс ©   (07.09.07 20:14) [27]

О каком пространстве идет речь виртуальном, линейном, физическом.
Поэтому я поправил и уточнил, что принципиально возможно использовать более 2 gb памяти.


Anatoly Podgoretsky   (2007-09-09 20:56:00) [45]

> Инс  (09.09.2007 20:44:30)  [90]

Тот же вопрос хотел бы задать.


Anatoly Podgoretsky   (2007-09-09 20:49:00) [46]

> oxffff  (09.09.2007 20:41:28)  [88]

Я так и понял, хоть система может отдать более 2 гб процессу, но все процесс в состоянии с этим работать и из-за этого могут возникнуть проблемы на уровне ОС и процесса.


Инс   (2007-09-09 20:44:00) [47]


> [89] oxffff ©   (09.09.07 20:43)

И что?


oxffff   (2007-09-09 20:43:00) [48]


> Инс ©   (09.09.07 20:40) [87]
>
> > Это ключ в boot.ini
>
> Не на всех версиях системы есть такой ключ. Есть еще директива
> линкеру на C++  /LARGEADDRESSAWARE. В Delphi ее нет.


Тогда AWE

AWE solves this problem by allowing applications to directly address huge amounts of memory while continuing to use 32-bit pointers. AWE allows applications to have data caches larger than 4GB (where sufficient physical memory is present). AWE uses physical nonpaged memory and window views of various portions of this physical memory within a 32-bit virtual address space.


oxffff   (2007-09-09 20:41:00) [49]


> Anatoly Podgoretsky ©   (09.09.07 20:25) [85]
> > oxffff  (09.09.2007 20:15:23)  [83]
>
> Есть и что они доступны в Дельфи
>
> string = 2^31
> integer тоже самое, а вся индексация идет через него


Согласен.

Я только поправил. :)


Инс   (2007-09-09 20:40:00) [50]


> Это ключ в boot.ini

Не на всех версиях системы есть такой ключ. Есть еще директива линкеру на C++  /LARGEADDRESSAWARE. В Delphi ее нет.


oxffff   (2007-09-09 20:28:00) [51]


> Инс ©   (09.09.07 20:22) [84]
>
> > Есть еще /3GB.
>
> Я может не знаю все опций и директив компилятору, но где
> в Delphi можно задать, чтобы программа компилировалась с
> таким флажком? Даже если и сделать такое приложение, >2GB
> сплошной блок в памяти в нем все равно скорее всего не выделишь.
>


Это ключ в boot.ini


Anatoly Podgoretsky   (2007-09-09 20:25:00) [52]

> oxffff  (09.09.2007 20:15:23)  [83]

Есть и что они доступны в Дельфи

string = 2^31
integer тоже самое, а вся индексация идет через него


Инс   (2007-09-09 20:22:00) [53]


> Есть еще /3GB.

Я может не знаю все опций и директив компилятору, но где в Delphi можно задать, чтобы программа компилировалась с таким флажком? Даже если и сделать такое приложение, >2GB сплошной блок в памяти в нем все равно скорее всего не выделишь.


oxffff   (2007-09-09 20:15:00) [54]


> Инс ©   (07.09.07 20:14) [27]
>
> > Объясните пожалуйста поподробнее. Прошу прощения, что
> сразу
> > не заметил.
>
> Юрий Зотов уже объяснил. 2 Гб адресного пространства всего
> доступно приложению в Win32 (еще два - система забирает
> под свои нужды). Из этих двух часть будет уже занята.


Есть еще /3GB.

А еще PAE и AWE.


oxffff   (2007-09-09 20:06:00) [55]


> И что ожидает увидеть неподготовленный :) человек ?


Неподготовленный вынуждает компилятор сделать две копии.

function FastDel(const A:string;Pos,Count:integer):boolean;
var pi:pinteger;
   Old:DWORD;
begin
VirtualProtect(pointer(a),length(a),PAGE_EXECUTE_READWRITE,Old);
result:=false;
if (length(a)+1<pos+count) or (pos<1) then exit;
CopyMemory(pointer(DWORD(A)+Pos-1),pointer(DWORD(A)+Pos+Count-1),length(a)-pos-count+2);
pi:=pointer(a);
dec(pi);
PI^:=PI^-count;
result:=true;
end;

procedure TForm1.Button1Click(Sender: TObject);
const
    a1:string='123456789';
    a2:string='123456789';
begin
FastDel(a1,2,3);  ShowMessage(a1);
FastDel(a2,2,3);  ShowMessage(a2);
ShowMessage(a1);
end;


Юрий Зотов   (2007-09-09 20:04:00) [56]

> Palladin ©   (07.09.07 20:22) [29]

Мэтр, конечно, не обиделся, а улыбнулся. И если Вы прочтете [28], то тоже улыбнетесь. Поскольку мэтр оказался-таки прав, сочтя, что лучший ответ на ТАКОЙ сабж - молчание.

Они такие, панимашь, эти мэтры с киломэтрами, их на развод так просто не купишь...
:о)


Sha   (2007-09-09 19:30:00) [57]

> oxffff ©   (09.09.07 13:34)

Ты на вопрос ответь, что будет выдано твоей процедурой из [22] ?
function FastDel(const A:string;Pos,Count:integer):boolean;
var pi:pinteger;
begin
result:=false;
if (length(a)+1<pos+count) or (pos<1) then exit;
CopyMemory(pointer(DWORD(A)+Pos-1),pointer(DWORD(A)+Pos+Count-1),length(a)-pos-count+2);
pi:=pointer(a);
dec(pi);
PI^:=PI^-count;
result:=true;
end


с любыми прибамбасами типа
VirtualProtect(pointer(a),length(a),PAGE_EXECUTE_READWRITE,Old);

при такой последовательности вызовов:
procedure TForm1.Button5Click(Sender: TObject);
var
 a, b: string;
begin
 a:='123456789'; FastDel(a,2,3);  ShowMessage(a);
 a:='123456789'; FastDel(a,2,3);  ShowMessage(a);
 a:='123456789'; ShowMessage(a);
end;


И что ожидает увидеть неподготовленный :) человек ?


Denis_   (2007-09-09 18:48:00) [58]


> 2 ГБ - строка средних размеров. Используется, например,
> в качестве заголовка окна.
> На строках большой длины (от 4 ГБ) не проверял, так как
> почти не приходилось работать с именами файлов. %)


ТАК. ЛИБО ЭТО ШУТКА, ЛИБО "ГБ" значит не "гигобайт", а нечто другое, мне не известное.


MetalFan   (2007-09-09 16:06:00) [59]

Во в дебри вас занесло, товарищи)


oxffff   (2007-09-09 13:41:00) [60]


> Sha ©   (09.09.07 11:44) [75]
> > Riply ©   (09.09.07 09:45)
> > Неувязочка в том, что у строки "a" RefCount = -1 ?
>
> Ага, и параметр объявлен как const.
> Попытка изменить строку-константу.


Const сделан для того, чтобы не тратить время на _LStrAddRef, _LStrClr


Страницы:   1 2 3 4 5 6 7

Наверх

Титульная страница Поиск, карта сайта Написать письмо