![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Удалить подстроку из очень большой строки (больше 2 ГБ ) [D7, WinXP]
*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 Гб. Не говря уже о других операциях. Надо что-то придумать.
Заранее всем ольшое спасибо за предложенные варианты!
Sha (2007-09-10 00:28:00) [1]> oxffff © (10.09.07 00:23) [135]
Не надо опасаться, что код создает уникальную копию константной строки.
Такие строки большими не бывают.
oxffff (2007-09-10 00:23:00) [2]
> Sha © (10.09.07 00:09) [132]
> > oxffff © (10.09.07 00:04) [129]
> > Для конст строки будет создан дублекат.
>
> В нашем случае это необходимо, иначе процедура будет неработоспособна.
>
Поэтому ваши замечания к моему коду и мои требования к вызову
virtualProtect и explicit constants(do not use shared const) исходили из
oxffff © [128]
oxffff (2007-09-10 00:12:00) [3]Я надеюсь мы наконец поняли друг друга.
И уверен сохраним самое главное - уважение друг другу.
Sha (2007-09-10 00:11:00) [4]> oxffff © (10.09.07 00:06) [130]
> Не удачно выразился.
Извинения приняты.
Впредь потрудись подбирать слова.
Sha (2007-09-10 00:09:00) [5]> oxffff © (10.09.07 00:04) [129]
> Для конст строки будет создан дублекат.
В нашем случае это необходимо, иначе процедура будет неработоспособна.
oxffff (2007-09-10 00:08:00) [6]
> А что нет? Читайте help
help кстати молчит по этому поводу. Только отладчик позволит выяснить истинное поведение
MOV ECX,[EDX-skew].StrRec.refCnt
DEC ECX
JE @@exit
oxffff (2007-09-10 00:06:00) [7]
> Вот это некрасиво - который раз уже
Не удачно выразился.
ПОД этим понимайте, что вы и я написали код, который не обрабатывает определенного вида ситуации. А не то о чем вы подумали. :)
oxffff (2007-09-10 00:04:00) [8]
> Почему?
> Разве он использует дополнительную память?
> Или делает лишние операции?
А что нет? Читайте help
Для конст строки будет создан дублекат.
oxffff (2007-09-10 00:02:00) [9]to Sha
Я нигде не указал, что мой пример пригоден для всего.
Когда его привел, я исходил из оптимизации.
И до последнего отстаивал его по причине не возможности выделить дополнительный блок памяти.
Sha (2007-09-09 23:58:00) [10]> oxffff © (09.09.07 23:44) [124]
>>> Эх профессиональный вы наш. :)
>> Профессионал может забыть, что-сделать,
>> а ламера надо заставлять это делать.
>> Почувствовал разницу?
> Ну вы и жук.
> Не красиво себя так вести.
А чем, по-твоему, отличается профессионал от ламера?
> Не надо выкручиваться. [62] не предусматривал работы с конст строками
> Доказательство комментарий
> q:=pointer(s); //чтобы компилятор не вставлял вызовы UniqueString
В инете дофига моего кода, работающего со строками, и везде
перед
q:=pointer(s); //чтобы компилятор не вставлял вызовы UniqueString
стоит
UniqueString(s);
> Так что руки растут от туда же.
Вот это некрасиво - который раз уже
> Далее по тексту. Про оптимизацию забыли?
> Мы работаем с большой строкой, так что ваш вариант - увы не может удовлетворить.
Почему?
Разве он использует дополнительную память?
Или делает лишние операции?
oxffff (2007-09-09 23:56:00) [11]
> Sha © (09.09.07 23:37) [123]
> > oxffff © (09.09.07 23:26) [121]
>
> > Эх профессиональный вы наш. :)
> Профессионал может забыть, что-сделать,
> а ламера надо заставлять это делать.
> Почувствовал разницу?
Я то почуствовал. Что так называемый профессионал пытался что то доказать, хотя обделался на том же самом и ему как профессионалу (а уж тем более МАСТЕРУ DELPHI), НЕЛЬЗЯ забывать что-то сделать, ибо тогда он не ПРОФЕССИОНАЛ (хотя не мне судить). Так что извольте погончики свои снять и сдать обратно.
oxffff (2007-09-09 23:47:00) [12]Что касаемо хелпа.
Я его читаю, но в нем (UniqueString help) не сказано про строки константы.
Тогда мне помогает отладчик.
oxffff (2007-09-09 23:44:00) [13]
> Sha © (09.09.07 23:37) [123]
> > oxffff © (09.09.07 23:26) [121]
>
> > Эх профессиональный вы наш. :)
> Профессионал может забыть, что-сделать,
> а ламера надо заставлять это делать.
> Почувствовал разницу?
Ну вы и жук.
Не красиво себя так вести.
Не надо выкручиваться. [62] не предусматривал работы с конст строками
Увы. Сами себя выдали.
Доказательство комментарий
q:=pointer(s); //чтобы компилятор не вставлял вызовы UniqueString
Так что руки растут от туда же.
> Это описано в хелпе, не поленись - прочитай.
oxffff © (09.09.07 23:30) [122]
Далее по тексту. Про оптимизацию забыли?
Мы работаем с большой строкой, так что ваш вариант - увы не может удовлетворить.
Sha (2007-09-09 23:37:00) [14]> oxffff © (09.09.07 23:26) [121]
> Эх профессиональный вы наш. :)
Профессионал может забыть, что-сделать,
а ламера надо заставлять это делать.
Почувствовал разницу?
> UniqueString(s) - создаст копию строки, если сможет.
> Не забываем об оптимизации.
> Две огромных строки - это не компромис.
UnicueString создат копию только в случае RO-строки или неуникальной,
т.е. как раз в том случае, как нам и надо.
Это описано в хелпе, не поленись - прочитай.
> Предлагаю оптимизировать ваш проверять RefCount на -1 и тогда делать
UniqueString.
Все сделано уже до нас в коде UniqueString. :)
oxffff (2007-09-09 23:30:00) [15]
> oxffff © (09.09.07 23:26) [121]
Ошибочка вышла UniqueString(s) этим и занимается.
oxffff (2007-09-09 23:26:00) [16]
> Sha © (09.09.07 23:17) [120]
> > oxffff © (09.09.07 22:57) [116] - [119]
>
> Конечно, надо вставить вызов
> UniqueString(s);
> перед оператором
> q:=pointer(s); //чтобы компилятор не вставлял вызовы UniqueString
> раз уж мы все делаем сами.
>
> Спасибо за найденную неточность :)
Эх профессиональный вы наш. :)
UniqueString(s) - создаст копию строки, если сможет.
Не забываем об оптимизации.
Две огромных строки - это не компромис.
Предлагаю оптимизировать ваш проверять RefCount на -1 и тогда делать
UniqueString.
Sha (2007-09-09 23:17:00) [17]> oxffff © (09.09.07 22:57) [116] - [119]
Конечно, надо вставить вызов
UniqueString(s);
перед оператором
q:=pointer(s); //чтобы компилятор не вставлял вызовы UniqueString
раз уж мы все делаем сами.
Спасибо за найденную неточность :)
oxffff (2007-09-09 23:10:00) [18]Добавьте
VirtualProtect(pointer(s),length(s),PAGE_EXECUTE_READWRITE,Old);
И проверьте свой же контр пример
procedure TForm1.Button1Click(Sender: TObject);
var b,c:string;
begin
c:='123456789';
DeleteString(c,'34');
showmessage(c);
c:='123456789';
DeleteString(c,'34');
showmessage(c);
end;
Так что руки у нас с вами из одного и того же места растут. LOL. :)
oxffff (2007-09-09 23:05:00) [19]Второй недостаток не подтвердился.
SysReallocMem позволяет сделать ResizeInPlace.
Ладно так что исправляйте первый. ;)
oxffff (2007-09-09 22:58:00) [20]Сейчас еще один недостаток проверю и найду.
Напросились сами.