Здравствуйте, Sinclair, Вы писали:
S> Простейшая штука — метод, получивший строку в начале исполнения, и выполнивший с ней некоторую проверку, хочет полагаться на то, что результат проверки не изменится. Никакими const этого добиться нельзя; придётся делать копию (которая скорее всего не нужна). Иммутабельную строку можно использовать в качестве ключа в коллекциях. Мутабельную — нельзя. И это только верхушка айсберга.
Var s : String;
Procedure ЗлобныйМетодИзменяющийСтроку;
Begin
s[1] := '-'; // срабатывает copy-on-writeEnd;
Procedure StringProc(AString : String);
Begin
Assert(AString = '123456789'); // наша важная проверка
ShowMessageFmt('%p', [Pointer(s)]); // посмотрим на адрес исходной строки
ЗлобныйМетодИзменяющийСтроку;
ShowMessageFmt('%p', [Pointer(s)]); // смотрим еще раз. адрес изменился. copy-on-write в действии
Assert(AString = '123456789'); // но переданная в параметре строка не измениласьEnd;
Begin
s := IntToStr(123456789);
StringProc(s); // при передаче строки RefCount будет увеличен (копия строки не создается)End;
Здравствуйте, hattab, Вы писали:
H>Здравствуйте, Sinclair, Вы писали:
S>> Простейшая штука — метод, получивший строку в начале исполнения, и выполнивший с ней некоторую проверку, хочет полагаться на то, что результат проверки не изменится. Никакими const этого добиться нельзя; придётся делать копию (которая скорее всего не нужна). Иммутабельную строку можно использовать в качестве ключа в коллекциях. Мутабельную — нельзя. И это только верхушка айсберга.
H>Какие-такие копирования
Прекрасно. Вы только что продемонстрировали реализацию иммутабельной строки.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[13]: ответ на вопрос: Почему новые программы работают меделнно
Здравствуйте, hattab, Вы писали:
S>> H>Какие-такие копирования S>> Прекрасно. Вы только что продемонстрировали реализацию иммутабельной строки. H>Дык в дельфях иммутабельных нет. Есть возможность правильного приготовления мутабельных.
Ну насколько я понял — в своём скопе — строка мутабельна, но передав её куда-нибудь — она становится иммутабельной, и при попытке её изменить, делается copy-on-write?
Re[15]: ответ на вопрос: Почему новые программы работают меделнно
Здравствуйте, fddima, Вы писали:
f> H>Дык в дельфях иммутабельных нет. Есть возможность правильного приготовления мутабельных.
f> Ну насколько я понял — в своём скопе — строка мутабельна, но передав её куда-нибудь — она становится иммутабельной, и при попытке её изменить, делается copy-on-write?
Здравствуйте, hattab, Вы писали:
f>> Ну насколько я понял — в своём скопе — строка мутабельна, но передав её куда-нибудь — она становится иммутабельной, и при попытке её изменить, делается copy-on-write? H>Нет, передать тоже можно по разному.
По разному можно очень много где, если очень захотеть.
Sinclair прав, твой пример показывает реализацию иммутабельных строк, хоть они из языка и видны как мутабельные.
Re[17]: ответ на вопрос: Почему новые программы работают меделнно
Здравствуйте, fddima, Вы писали:
f> H>Нет, передать тоже можно по разному.
f> По разному можно очень много где, если очень захотеть.
Очень захотеть? Вообще-то var один из обычных способов передачи параметра И это будет та-же самая строка, а не пришейзвиздерукавстрингбилдер.
f> Sinclair прав, твой пример показывает реализацию иммутабельных строк, хоть они из языка и видны как мутабельные.
Здравствуйте, fddima, Вы писали: F> Ну насколько я понял — в своём скопе — строка мутабельна, но передав её куда-нибудь — она становится иммутабельной, и при попытке её изменить, делается copy-on-write?
Нет, она всегда иммутабельна.
При передаче "по ссылке" изменяется не строка, а значение ссылки.
Ровно ту же реализацию мы имеем в C#, но почему-то там никто не говорит о "мутабельности" строк.
Единственная разница — в контроле за временем жизни. В Delphi строки финализируются детерминистически на основе счётчика ссылок (это не приводит к традиционным для рефкаунта проблемам потому, что строка не может быть частью цикла ссылок). В шарпе — собираются сборщиком мусора.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[18]: ответ на вопрос: Почему новые программы работают меделнно
Здравствуйте, hattab, Вы писали:
H>Здравствуйте, fddima, Вы писали:
f>> H>Нет, передать тоже можно по разному.
f>> По разному можно очень много где, если очень захотеть.
H>Очень захотеть? Вообще-то var один из обычных способов передачи параметра И это будет та-же самая строка, а не пришейзвиздерукавстрингбилдер.
Нет, это будет совсем другая строка.
Procedure ЗлобныйМетодИзменяющийСтроку(var arg:string);
Begin
arg[1] := '-'; // срабатывает copy-on-writeEnd;
Procedure StringProc(AString : String);
var
localString: String;
Begin
Assert(AString = '123456789'); // наша важная проверка
localString = AString;
ShowMessageFmt('%p', [Pointer(localString)]); // посмотрим на адрес исходной строки
ЗлобныйМетодИзменяющийСтроку(localString);
ShowMessageFmt('%p', [Pointer(localString)]); // смотрим еще раз. адрес изменился. То есть нам вернули совсем другую строку.
Assert(AString = '123456789'); // но переданная в параметре строка не изменилась
ShowMessageFmt('%p', [Pointer(AString)]); // как и её адресEnd;
Begin
StringProc(IntToStr(123456789));
End;
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[19]: ответ на вопрос: Почему новые программы работают меделнно
Здравствуйте, Sinclair, Вы писали:
S> H>Очень захотеть? Вообще-то var один из обычных способов передачи параметра И это будет та-же самая строка, а не пришейзвиздерукавстрингбилдер.
S> Нет, это будет совсем другая строка.
...
Имеется ввиду, что в StringProc её нужно передать как var
Здравствуйте, hattab, Вы писали:
H>Имеется ввиду, что в StringProc её нужно передать как var
Это понятно. И тем не менее, вернётся совсем другая строка.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[21]: ответ на вопрос: Почему новые программы работают меделнно
Здравствуйте, Sinclair, Вы писали:
S> H>Имеется ввиду, что в StringProc её нужно передать как var
S> Это понятно. И тем не менее, вернётся совсем другая строка.
В моем коде, где не создается копия строки (localString := AString), это будет та же самая строка.
Здравствуйте, hattab, Вы писали:
H>В моем коде, где не создается копия строки (localString := AString), это будет та же самая строка. Оптимизация копирований при refCount == 1? Ничего принципиально интересного это не даёт. Поведение строки в дельфи абсолютно аналогично поведению строки в шарпе. Включая поведение при передаче параметра с var.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[18]: ответ на вопрос: Почему новые программы работают мед
Здравствуйте, Ночной Смотрящий, Вы писали:
НС>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>Мне это известно. А все же, можно объяснить, как тут возникает N^4.
НС>В гугле не нашел, а мне расписывать с таким отношением лень. Одно дело если бы тебя действительно вопрос интересовал, а другое когда ты явно хочешь очередную пургу про криворуких программистов прогнать.
Ну мне, например, тоже интересно, как такая сильная зависимость возникает, и ради чего не идут на меньшую зависимость? Ну там невозможно в принципе, очень сложно, очень медленно и т. д...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[23]: ответ на вопрос: Почему новые программы работают меделнно
Здравствуйте, Sinclair, Вы писали:
S> H>В моем коде, где не создается копия строки (localString := AString), это будет та же самая строка.
S> Оптимизация копирований при refCount == 1? Ничего принципиально интересного это не даёт.
Ну вот у меня в парсере, как раз такой случай. Строка для всевозможных обработок отдается на модификацию, и у неё всегда refCount = 1. Ненужного копирования не происходит.
S> Поведение строки в дельфи абсолютно аналогично поведению строки в шарпе. Включая поведение при передаче параметра с var.
M>Современный C++ даже Edit & Continue уже умеет. Но это достигается искючительно магией, ага.
Зачем для этой фичи много памяти при компиляции?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[23]: ответ на вопрос: Почему новые программы работают мед
Здравствуйте, rameel, Вы писали:
R>Кстати, интересно, что если лямбда содержит вложенные лямбды, то это процесс может вызываться рекурсивно. Я, кажется, когда-то приводил пример, когда это вызывает комбинаторный взрыв: R>
Во-первых, большое спасибо за конкретику. Это возвращает обсуждение в конкретное и конструктивное русло!
Во-вторых, Верно ли я понял, что N тут -- это "глубина вложенности лямбд"?
Если да, то я предлагаю обсудить прожорливость компиляторов, в случае кода, не содержащего рекурсивных лямбд...
Просто обсуждавшийся тут "однометровый паскаль" можно было осоо навёрнутой прогой уронить, ну и аналогичный "десятиметровый шарп" тоже бы тут падал, или взрывался бы, но это никак не повод на всех остальных программах хотеть 100 метров...
R>А вот другой пример, в котором программа в 62 байта напрягает компилятор шарпа так, что современный процессор жжет кислород около минуты R>Re[6]: [Этюд, C#] Долгая компиляция
class X<A,B,C,D,E>{class Y:X<Y,Y,Y,Y,Y>{Y.Y.Y.Y.Y.Y.Y.Y.Y y;}}
PD>>Но как из исходного файла в 1 Мб образуется объем промежуточных данных, скажем, в 100 Мб — твой ликбез не объясняет.
IMHO это всё никому не нужно. Компилятор мог бы просто падать и не плодить много метров мусора...
R>Вот последний пример, кроме долгой компиляции, порождает сборку размером почти в 28 Мб.
В-третьих, мне лично неочевидно, что для компиляции примера с Foo и лямбдами, нужно таки экспоненциальное время и память...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[24]: ответ на вопрос: Почему новые программы работают мед
Здравствуйте, Mamut, Вы писали:
E>>Зачем для этой фичи много памяти при компиляции? M>Так не только же для этой фичи
Дык зачем тогда приводить эту фичу качестве объяснения роста аппетитов компиляторов?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[25]: ответ на вопрос: Почему новые программы работают мед
E>>>Зачем для этой фичи много памяти при компиляции? M>>Так не только же для этой фичи
E>Дык зачем тогда приводить эту фичу качестве объяснения роста аппетитов компиляторов?
Ты думаешь, анализ и расставление меток для Edit&Continue даются даром?