Re[30]: Ну ты вообще многого не видишь... ;)
От: WolfHound  
Дата: 04.06.09 19:37
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>Для редактора текстов заметно лучше подходят строки с gap-буффером.

1)Советую ознакомиться с паттерном zipper.
2)А если рассматривать задачу в комплексе те вспомнить про undo/redo то кто кого порвет мы еще посмотрим...
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[39]: Ну ты вообще многого не видишь... ;)
От: Геннадий Васильев Россия http://www.livejournal.com/users/gesha_x
Дата: 04.06.09 21:17
Оценка:
Здравствуйте, WolfHound, Вы писали:

ГВ>>Просто такой подход сработает только на длинных строках и только для модификаций. На коротких дешевле будет обычный буфер (в который, в общем-то и должен бы превратиться rope). Ну и иммутабельность должна ещё повлиять: модификации иммутабельного rope будут, конечно, быстрее, чем модификации длинных иммутабельных буферов, но прилично медленнее, чем мутабельных rope-ов.

WH>С какой стати?
WH>Создание узлов операция очень дешевая.

Это ты из принципа? Очень дешёвая — но всё равно же не нуль.

WH>>>>>Нет. Им достаточно хранить количество символов в собственной подстроке.

ГВ>>>>Нет, этого мало.
WH>>>Для чего конкретно этого не хватает?
ГВ>>Для доступа по индексу, очевидно.
WH>Те по твоему нельзя реализовать доступ по индексу если каждый узел знает только размер своей подстроки?
WH>Я правильно тебя понял?

Нет, не правильно ты меня понял. Реализовать-то можно, только потери по скорости будут.

ГВ>>rope тут всегда проиграет буферу, опять таки, за исключением коротких строк или случая с небольшой глубиной дерева — здесь они будут практически равны.

WH>Опять таки зачем конкретно нужен доступ по индексу к одиночному элементу?

Есть, например, EDI-протоколы, формат сообщений которых предполагает фиксированные позиции элементов.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Re[39]: Ну ты вообще многого не видишь... ;)
От: Геннадий Васильев Россия http://www.livejournal.com/users/gesha_x
Дата: 04.06.09 21:54
Оценка:
Здравствуйте, WolfHound, Вы писали:

ГВ>>P.S.: Ссылку посмотрел, спасибо. Причины заморочек, ИМХО, понятны — похоже, как раз из-за индексного доступа или требования преобразования к линейному буферу.

WH>Нет.
WH>Там заморочки из серии:
WH>

WH>Astute readers might wonder why charAt is more than seven times faster than the iterator, given that both provide O(1) access time. This difference is due to the fact that in the Java language, Iterators must return Objects. Although the charAt implementation directly returns char primitives, the iterator implementation must box each char into a Character object. Auto-boxing might sooth the syntactic pain of primitive boxing, but it can't eliminate the performance penalties.


Ну боксинг, так боксинг.

WH>.NET 2.0 и старше конкретно этой заморочкой не страдает.

WH>Хотя и он весьма ущербен.

И .Net ущербен, и Java — не язык, и C++ — убожество. Инверсный Блаб-парадокс в действии.

WH>Короче тут нужно делать нормальную ВМ с нормальным оптимизатором.


Понеслась коза по рельсам...

WH>Тогда ропы или пальчиковые деревья (надо смотреть что лучше) будут рулить со страшной силой.


Ну "нормальная ВМ" с "нормальным оптимизатором" вообще будет рулить не по-детски и анализировать граф исполнения сможет с учётом всех возможных данных за время, стремящееся к нулю, кто ж спорит?!
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Re[30]: Ну ты вообще многого не видишь... ;)
От: Sinclair Россия https://github.com/evilguest/
Дата: 05.06.09 03:35
Оценка:
Здравствуйте, WFrag, Вы писали:
WF>В терминах O-большого или с учётом константы?
По идее — без. Короткие rope выродятся в полный аналог String.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[31]: Ну ты вообще многого не видишь... ;)
От: WFrag США  
Дата: 05.06.09 03:40
Оценка:
Здравствуйте, Sinclair, Вы писали:

WF>>В терминах O-большого или с учётом константы?

S>По идее — без. Короткие rope выродятся в полный аналог String.

Да, но Wolfhound предлагает устранить и StringBuilder.

Мне непонятно, как тогда rope получится эффективно удовлетворить оба пункта:

1) Иммутабельные строки, конкатенация длинных строк <-- вот тут rope замечательно подходят (опуская проблемы отдельно взятых VM)
2) Эффективная конкатенация мелочёвки (скажем, по нескольку символов). <-- А тут как быть? Создавать новые листья или узлы деревьев? Как-то неэффективно.
Re[32]: Ну ты вообще многого не видишь... ;)
От: Sinclair Россия https://github.com/evilguest/
Дата: 05.06.09 04:10
Оценка:
Здравствуйте, WFrag, Вы писали:

WF>1) Иммутабельные строки, конкатенация длинных строк <-- вот тут rope замечательно подходят (опуская проблемы отдельно взятых VM)

WF>2) Эффективная конкатенация мелочёвки (скажем, по нескольку символов). <-- А тут как быть? Создавать новые листья или узлы деревьев? Как-то неэффективно.
Не вижу, почему бы это было неэффективно.
В случае
while()
  rope = rope.Append((Char)random.Next(Char.Maxvalue));

всё будет работать как минимум не хуже, чем со StringBuilder:
1. Буфер под узел выделен с запасом; поэтому можно дописывать ему в конец символы, не разрушая предыдущие значения rope.
2. Когда кончится буфер, создадим новый узел. Это недорого.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[33]: Ну ты вообще многого не видишь... ;)
От: WFrag США  
Дата: 05.06.09 04:36
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Не вижу, почему бы это было неэффективно.

S>В случае
S>
S>while()
S>  rope = rope.Append((Char)random.Next(Char.Maxvalue));
S>

S>всё будет работать как минимум не хуже, чем со StringBuilder:
S>1. Буфер под узел выделен с запасом; поэтому можно дописывать ему в конец символы, не разрушая предыдущие значения rope.
S>2. Когда кончится буфер, создадим новый узел. Это недорого.

А как же иммутабельность? Получается, либо мы создаём новый объект кадый раз (например, rope, который указывает на то же дерево данных, НО имеет длину + 1), либо мы меняем существующий объект. Но у нас нет разделения неизменямый/изменяемый (String/StringBuilder), состояние какого объекта мы будем менять?
Re[34]: Ну ты вообще многого не видишь... ;)
От: Sinclair Россия https://github.com/evilguest/
Дата: 05.06.09 05:02
Оценка:
Здравствуйте, WFrag, Вы писали:

WF>А как же иммутабельность? Получается, либо мы создаём новый объект кадый раз (например, rope, который указывает на то же дерево данных, НО имеет длину + 1), либо мы меняем существующий объект. Но у нас нет разделения неизменямый/изменяемый (String/StringBuilder), состояние какого объекта мы будем менять?

А в чём проблема? Ну создали мы новый rope; он показывает на дерево данных, построенное на тех же буферах, что и предыдущий rope.
Представь, что ты решаешь обратную задачу:
rope1 = rope0.Left(rope0.Length-1);

Ведь понятно же, почему при этой операции не нужно никаких копирований буферов? Ну вот конкатенация делает то же самое, только наоборот.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[35]: Ну ты вообще многого не видишь... ;)
От: WFrag США  
Дата: 05.06.09 05:31
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>А в чём проблема? Ну создали мы новый rope; он показывает на дерево данных, построенное на тех же буферах, что и предыдущий rope.

S>Представь, что ты решаешь обратную задачу:
S>
S>rope1 = rope0.Left(rope0.Length-1);
S>

S>Ведь понятно же, почему при этой операции не нужно никаких копирований буферов? Ну вот конкатенация делает то же самое, только наоборот.

Да, но тут нужно создавать новый экземпляр rope (а это память). Добавляя 10 раз по одному символу создадутся 10 экземпляров rope (пусть даже и разделяющих общий буффер с данными). А в случае «классического» StringBuilder-а ничего создавать не нужно (пока хватает capacity буффера) — увеличиваем длину и меняем элементы массива.

Если бы речь шла просто о замене внутренней структуры String и StringBuilder-а с массива на rope (с тем отличием, что StringBuilder может менять своё состояние), то я бы согласился — никаких проблем, можно сделать не хуже обычных String/StringBuilder на массивах. Но, насколько я понял, речь-то идёт о том, что оставить один контракт, иммутабельный String.
Re[36]: Ну ты вообще многого не видишь... ;)
От: Sinclair Россия https://github.com/evilguest/
Дата: 05.06.09 05:54
Оценка: +1
Здравствуйте, WFrag, Вы писали:

WF>Да, но тут нужно создавать новый экземпляр rope (а это память).

Э-э, как только память станет проблемой, её уберёт GC.
С System.String корень неэффективности именно в копировании буферов, т.е. стоимость любой операции в O(N). В rope это будет O(Log(N)), стремящийся к O(1) в простых случаях.

WF>Если бы речь шла просто о замене внутренней структуры String и StringBuilder-а с массива на rope (с тем отличием, что StringBuilder может менять своё состояние), то я бы согласился — никаких проблем, можно сделать не хуже обычных String/StringBuilder на массивах. Но, насколько я понял, речь-то идёт о том, что оставить один контракт, иммутабельный String.


Тут нужно много чего мерить, и следить за поведением VM. Я так понял, что не всякая VM даст реализовать rope с такой эффективностью, чтобы забить StringBuilder на всех сценариях.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
У них в описании должно быть
От: Mamut Швеция http://dmitriid.com
Дата: 05.06.09 06:31
Оценка:
WF> Если бы речь шла просто о замене внутренней структуры String и StringBuilder-а с массива на rope (с тем отличием, что StringBuilder может менять своё состояние), то я бы согласился — никаких проблем, можно сделать не хуже обычных String/StringBuilder на массивах. Но, насколько я понял, речь-то идёт о том, что оставить один контракт, иммутабельный String.

В тексте про ropes должно быть это описано: http://www.cs.ubc.ca/local/reading/proceedings/spe91-95/spe/vol25/issue12/spe986.pdf
avalon 1.0rc1 rev 239, zlib 1.2.3


dmitriid.comGitHubLinkedIn
Re[37]: Ну ты вообще многого не видишь... ;)
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 05.06.09 06:37
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, WFrag, Вы писали:


WF>>Да, но тут нужно создавать новый экземпляр rope (а это память).

S>Э-э, как только память станет проблемой, её уберёт GC.
S>С System.String корень неэффективности именно в копировании буферов, т.е. стоимость любой операции в O(N). В rope это будет O(Log(N)), стремящийся к O(1) в простых случаях.

При этом пробег по непрерывной памяти значительно эффективней. Затраты одного создания может быть значительно меньше, затрат на прыжки по узлам.
Плюс GC так или иначе будет дефрагментировать память вместе со строками вкучу, и эффект не копирования буферов сведется если не на нет, то значительно.
Сильно зависит от отношения поиска по строке, и изменением размера строки.
и солнце б утром не вставало, когда бы не было меня
Re[35]: Ну ты вообще многого не видишь... ;)
От: CreatorCray  
Дата: 05.06.09 07:18
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, CreatorCray, Вы писали:

S>>>Thread_safe_string крайне труден в написании.
CC>>Да ну??? Неужто написать COW строку на refcounterах так сложно?
S>И она будет прямо таки вся thread safe?
Будет.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[35]: Ну ты вообще многого не видишь... ;)
От: CreatorCray  
Дата: 05.06.09 07:18
Оценка:
Здравствуйте, WolfHound, Вы писали:

CC>>Да ну??? Неужто написать COW строку на refcounterах так сложно?

WH>Чтобы она еще и работала быстро на многопроцессорной тачке очень сложно.
Не очень. Никто в здравом уме не станет делать полную копию интерфейса мутабельной строки.
По сути по использованию (интерфейсу) thread_safe_string получится почти такая же immutable string как и в шарпе. Некоторые фичи mutable строк (напр. неконстантный operator[] и т.п.) будут разумеется отрезаны.
Ну и GC будет заменен refcounter-ами на буфер строки.

WH>Ибо даже InterlockedIncrement/InterlockedDecrement весьма не бесплатны на многопроцессорных машинах.

Не бесплатны, но и не экстра-дороги.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[27]: Ну ты вообще многого не видишь... ;)
От: Pavel Dvorkin Россия  
Дата: 05.06.09 08:07
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Здравствуйте, Pavel Dvorkin, Вы писали:


PD>>char szString[N];

PD>>gets(szString);
PD>>strupr(szString);

PD>>и ни одного лишнего байта. Можно такое сделать ?

WH>Что сделать?
WH>Проезд по памяти?

Угу. С преобразованием к верхнему регистру для каждого проезжаемого символа.

WH>Конечно нет.


Именно.
With best regards
Pavel Dvorkin
Re[11]: За что я не люблю С++
От: jazzer Россия Skype: enerjazzer
Дата: 05.06.09 08:12
Оценка: +2 :)
Здравствуйте, criosray, Вы писали:

C>http://hestia.typepad.com/flatlander/2008/12/c-covariance-and-contravariance-by-example.html


Напугали ежа
В большинстве случаев это не нужно (потому что шаблоны используют утиную типизацию), а если понадобилось все-таки это использовать, то достаточно просто повесить ассерт на is_base_of (в числе прочих ассертов, кстати — мало ли что тебе понадобится, ко/контравариантностью дело не исчерпывается обычно, простейший пример — контейнер).

Шаблонов у вас нету в шарпе нормальных, вот и приходится извращаться.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[31]: Ну ты вообще многого не видишь... ;)
От: Cyberax Марс  
Дата: 05.06.09 09:18
Оценка:
Здравствуйте, WolfHound, Вы писали:

C>>Для редактора текстов заметно лучше подходят строки с gap-буффером.

WH>1)Советую ознакомиться с паттерном zipper.
Ознакомился.

WH>2)А если рассматривать задачу в комплексе те вспомнить про undo/redo то кто кого порвет мы еще посмотрим...

А что с ними не так у gap buffers?
Sapienti sat!
Re[40]: Ну ты вообще многого не видишь... ;)
От: WolfHound  
Дата: 05.06.09 10:12
Оценка:
Здравствуйте, Геннадий Васильев, Вы писали:

ГВ>Это ты из принципа? Очень дешёвая — но всё равно же не нуль.

А модификация типа нуль?

ГВ>Нет, не правильно ты меня понял. Реализовать-то можно, только потери по скорости будут.

С какой стати?
Решение в каждом узле принимается за O(1) с весьма маленьким О.

ГВ>Есть, например, EDI-протоколы, формат сообщений которых предполагает фиксированные позиции элементов.

Дай ссылку на толковое описание. А то я что-то один маркетинговый булщит нахожу.
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[36]: Ну ты вообще многого не видишь... ;)
От: WolfHound  
Дата: 05.06.09 10:15
Оценка:
Здравствуйте, CreatorCray, Вы писали:

CC>Не очень. Никто в здравом уме не станет делать полную копию интерфейса мутабельной строки.

И не надо. Счетчика ссылок достаточно.

CC>Ну и GC будет заменен refcounter-ами на буфер строки.

Во-во...

WH>>Ибо даже InterlockedIncrement/InterlockedDecrement весьма не бесплатны на многопроцессорных машинах.

CC>Не бесплатны, но и не экстра-дороги.
Достаточно дороги чтобы в большинстве случаев было выгоднее копирование, а не счетчик ссылок.
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[32]: Ну ты вообще многого не видишь... ;)
От: WolfHound  
Дата: 05.06.09 10:22
Оценка:
Здравствуйте, Cyberax, Вы писали:

WH>>1)Советую ознакомиться с паттерном zipper.

C>Ознакомился.
Значит теперь ты сможешь осознать что гапнуть ропу зиппером ни разу не проблема.

WH>>2)А если рассматривать задачу в комплексе те вспомнить про undo/redo то кто кого порвет мы еще посмотрим...

C>А что с ними не так у gap buffers?
А то что их нужно делать.
Нужно придумать структуры данных.
Реализовать без ошибок.
Поддерживать их в актуальном состоянии.
...

А в случае с rope у нас все получается бесплатно.
Все что нужно это добавить 2 односвязных списка.
Один для undo второй для redo.
А односвязные списки как ты понимаешь в любом функциональном языке буквально везде.
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.