Здравствуйте, Oyster, Вы писали:
O>Как видите, сначала идут 4 call к SomeFuncReturningString(), а потом только один call string.Concat. Выходит, вы неправы, уважаемый adontz?
Хммм странно. Я постараюсь создать минимальный проект повторяющий отсутсвие оптимизации.
Здравствуйте, Oyster, Вы писали:
O>>А почему вы решили, что
O>>
O>>// это то, во что преобразится string z = x + GenerateLongString()+y;
O>>string z = string.Concat(x, GenerateLongString(), y);
O>>
O>>будет менее оптимально, чем
потому, что требуется в буфере места для GenerateLongString() плюс место на саму возвращаемую строку, а в нижнем примере всё выводится сразу в буфер. Выиграш, на длину возвращаемой строки. И это не всё. Если в том вызове много конкатенаций, то всё это — создание временных объектов, а значит лишняя нагрузка. Этот как разница между DOM и SAX.
ANS>>>>>
Здравствуйте, Andrei N.Sobchuck, Вы писали:
ANS>потому, что требуется в буфере места для GenerateLongString() плюс место на саму возвращаемую строку, а в нижнем примере всё выводится сразу в буфер. Выиграш, на длину возвращаемой строки. И это не всё. Если в том вызове много конкатенаций, то всё это — создание временных объектов, а значит лишняя нагрузка. Этот как разница между DOM и SAX.
Упс... да, тут я совсем неправ. Для таких случаев StringBuilder, конечно, эффективнее — это бесспорно.
Здравствуйте, Quintanar, Вы писали:
Q>Вектор — это просто одномерный массив, а по простому отображение множества {1..N} в множество некоторых элементов.
Ну, пожалуй, не просто одномерный массив: если подразумевать вектор в смысле элемента линейного пространства, то важны свойства операций над ним.
Q> В твоем примере сразу виден порочный подход к перегрузке операторов, типичный для "свободного" С++ника. Арифметическое произведение использовано для скалярного произведения, чем сразу же нарушаются все мыслимые свойства операции *, которые мы вправе от нее ожидать. Использовать * для векторного произведения тоже нельзя, поскольку векторное произведение не коммутативно.
А почему обязательно считать, что произведение в данном случае — операция арифметическая? Дальше, коммутативность не есть обязательное свойство умножения, по крайней мере, в теории групп. Может, ты хотел написать вместо "коммутативность" "ассоциативность", т.к. последнее, действительно, есть необходимое свойство умножения (с позиции теории групп)? Выводы, правда, остаются теми же самыми. Использовать * для векторного произведения неудачно, т.к. нарушаются совсем базовые свойства умножения: нет ассоциативности, нет "единицы", нет обратного элемента и т.п.
Есть еще одна, имхо, более существенная, причина, почему в общем случае использовать * для векторного произведения нет смысла: векторное "произведение" для двух "множителей" определено только для трехмерных векторов. В случае n-мерных векторов операндов будет n-1, что, очевидно, с помощью operator * выразить не удастся.
Третья причина заключается в неоднозначности чтения кода a * b в случае векторов. Читатель может воспринимать это как "скалярное произведение" (что arguably может быть более естественным), так и как "векторное произведение".
Q>В математике есть определенная иерархия структур типа полугруппа, группа, ассоциативная группа, полукольцо, кольцо и т.д. Все что встречается на практике неизбежно попадает под одно из определений, так что особо думать не надо.
Да, похоже, все-таки речь шла о произведении в смысле операции, задающей группу. Тогда о коммутативности стоит говорить только для абелевых групп, что обязательным требованием не является.
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, Andrei N.Sobchuck, Вы писали:
ANS>Кстати, вопрос к знатокам .Net. В Java (вроде начиная с 1.5) можно стринг билдер сделать взаимозаменяемым с потоком вывода (они поддерживают интерфейс Appendable). А как с этим дело в C#?
Здравствуйте, Quintanar, Вы писали:
ГВ>>Мне не мешает управление памятью. Наоборот — красивое решение содержит в себе элегантное управление памятью (вернее — жизненным циклом объектов, а не памятью как таковой) как неотъемлемую часть. И не надо сравнивать с математикой — любая формула из ВМ включает в себя элементарные операции сложения/умножения.
Q>Если бы каждый элегантно разрабатывал бы болты под себя, а не пользовался набором стандартных, то цивилизации не существовало бы.
Интересно, а откуда бы тогда болты взялись?
Q>Конструктор может позволить себе не заниматься такими мелочами, а сконцентрироваться на машине в целом.
Хороший конструктор обычно помнит о том, что болты должны быть из стали XXXXX, а не из абы-чего-лишь-бы-с-резьбой и при этом вполне помнит и о машине в целом.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, VladD2, Вы писали:
ГВ>>Как минимум, она позволяет писать обобщённые конструкции, [...]
VD>[...] А ведь казалось бы ЖЦ и делегаты решили бы все проблемы.
Ну, кто о чём...
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, Quintanar, Вы писали:
VD>>Есть такая штука — практика. И она показывает, что никаких проблем перегрузка не вызывает. На практике никто не кидается перегружать все какие можно операторы для все попавшихся под руку типов. Те кто может навалять дурака просто недодумываются применить это средство.
Q>Никаких доказательств этим утверждениям нет, поэтому стоит убрать из рассмотрения.
Есть вещи которые не нужно доказывать. Кстати, доказательств неприемлемости "+" для конкатинации тоже нет и быть не может. Это разговоры о вкусах и привычках. Но то что проблем со сложением строк нет можно опровергнуть. Попробуй найти чью нибудь жалобу на то, что он не понял что такое "а" + "б". Я таких не встречал.
... << RSDN@Home 1.2.0 alpha rev. 591>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, adontz, Вы писали:
A>Если уж на то пошло откровенная ерунда это то, что говоришь
Слава богу не тебе об этом судить.
A> Выдрал какой-то куцый пример и обрадовался.
Я что-то выдерал? Та в очередной раз начал рассуждать о сложении строк через "+" основываясь на своих тараканах почерпнутых в С++. Я тебе заметил, что ты заблуждашся. Ты вместо того чтобы разобраться и запомнить, что не все делается аналогично тому как это сделано в С++, откровенно соврал, что посмотрел сгенерированный код.
Странно, что тебе приходится пересказывать события просходящие с тобой лично.
A>Складывать строки когда они так навиду не велика заслуга.
Ну, где как. В Шарпе не сомненн.
A> Что-то я в более жизненных случаях никаких оптимизаций от компилятора не заметил.
Чем случай не жиненный? Я так постоянно пользуюсь сложением строк. А если нужно что-то в цикле складывать создаю StringBuilder. И жить становится просто, сухо и т.п.
A> Так что я не понял что ты пытаешься доказать?
Ничего. Просто обратил внимание окружающих на то что твои расуждения и утверждения далеки от реальности.
A> Что компилятор в искуственно упрощённом коде может что-то оптимизировать? Ура!
Ура!
A>
A>using System;
A>namespace cstest
A>{
A> class CSTest
A> {
A> static string SomeFuncReturningString()
A> {
A> return"qwerty";
A> }
A> [STAThread]
A> static void Main(string [] args)
A> {
A> string a = "aaa";
A> string b = "bbb";
A> string c = "ccc";
A> string d = "ddd";
A> string e = SomeFuncReturningString() + SomeFuncReturningString() + SomeFuncReturningString() + SomeFuncReturningString();
A> }
A> }
A>}
A>
Это откровение? Что ты хотел этим сказать, то?
Кстати, хочешь расскажу что будет в приведенном тбою примере?
Так вот, строка:
string e = SomeFuncReturningString()
+ SomeFuncReturningString()
+ SomeFuncReturningString()
+ SomeFuncReturningString();
Превратится компилятором C# в:
string e = string.Concat(SomeFuncReturningString(),
SomeFuncReturningString(),
SomeFuncReturningString(),
SomeFuncReturningString());
если эту программу запустить в релизе, то JIT произведет подстановку тел SomeFuncReturningString() и код получится:
string e = string.Concat("qwerty", "qwerty", "qwerty", "qwerty");
Дальше у компилятора скорее всего фантазия не пойдет. Но пример твой надумнный и в жизни строки бы все равно были бы не статическими и их пришлось бы конкатинировать. В общем, скорость была бы очень даже высокая.
... << RSDN@Home 1.2.0 alpha rev. 591>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, adontz, Вы писали:
A>Это как? C# Compiler генерирует IL. Но IL не выполняется, .Net Framework его сперва компилирует в машинный код (ассемблер просто более человечное его представление). Вот сгенерированный ассемблерный код я и глядел
Ой, а может поделишся как ты это делашь? Я лично знаю только один способ и им чертовски не удобно пользоваться. Но этот способ не подразумевает что в ехе-шнике может быть ассеблерный код. Все же джит и все такое...
Правда к делу это отношения не имеет, так как подстановка string.Concat делается компилятором C# и смотреть ассемблер не нужно.
... << RSDN@Home 1.2.0 alpha rev. 591>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Oyster, Вы писали:
O>Как видите, сначала идут 4 call к SomeFuncReturningString(), а потом только один call string.Concat. Выходит, вы неправы, уважаемый adontz?
Чтобы увидить настоящий код генерируемый джитом в оптимизированном (в релизе при запуске без отладчика) режиме нужно ползоваться cordbg.exe. Причем нужно задавать опцию "m JitOptimizations 1". Ди и то не факт, что код будет таким же как при обычном запуске. Вот как этовыглядит для данного примера:
C:\MyProjects\Tests\StrConcatCs\StrConcatCs\bin\Release>c:\VS\VS2005\SDK\v2.0\Bin\cordbg.exe StrConcatCs.exe
Microsoft (R) Common Language Runtime Test Debugger Shell Version 2.0.50215.44 (beta2.050215-4400)
Copyright (C) Microsoft Corporation. All rights reserved.
(cordbg) run StrConcatCs.exe
Process 8488/0x2128 created.
Warning: couldn't load symbols for C:\WINDOWS\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll
[thread 0x2408] Thread created.
025: A.Test();
(cordbg) m JitOptimizations 1
JIT's will produce optimized code
(cordbg) si
014: _e = SomeFuncReturningString()
(cordbg) sh
009: return "qwerty";
010: }
011:
012: public static void Test()
013: {
014:* _e = SomeFuncReturningString()
015: + SomeFuncReturningString()
016: + SomeFuncReturningString()
017: + SomeFuncReturningString();
018: }
019: }
(cordbg) dis 25
[0000] push edi
[0001] push esi
[0002] push ebx
[0003] push ebp
[0004] cmp dword ptr ds:[001A278Ch],0
[000b] je 00000007
[000d] call 7674500C
*[0012] call dword ptr ds:[03180D80h]
[0018] mov ebp,eax
[001a] call dword ptr ds:[03180D80h]
[0020] mov ebx,eax
[0022] call dword ptr ds:[03180D80h]
[0028] mov esi,eax
[002a] call dword ptr ds:[03180D80h]
[0030] mov edi,eax
[0032] push esi
[0033] push edi
[0034] mov edx,ebx
[0036] mov ecx,ebp
[0038] call dword ptr ds:[031670A4h]
[003e] mov esi,eax
[0040] lea edx,ds:[01B41F34h]
[0046] call 7651C908
[004b] nop
[004c] pop ebp
[004d] pop ebx
[004e] pop esi
[004f] pop edi
[0050] ret
(cordbg) ex
Terminating current process...
Process exited.
... << RSDN@Home 1.2.0 alpha rev. 591>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Oyster, Вы писали:
VD>>>Врешь.
A>>Мда. Приехали
O>Почему это? Ты же говорил, что смотрел сгенерированный код, верно? Я давал пример, опровергавший твоё утверждение: Re[22]: No String Builder
Это видимо такая неуклюжая попытка сохранить хорошую мину при плохой игре. Мол переход на личности и все такое. Не признавать, же что ничего не смотрел?
... << RSDN@Home 1.2.0 alpha rev. 591>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Мужики, вы что? Столько умных слов чтобы обосновать неприемлемость знака "+" для конкатинации стро? Да каждый ребоенок поймет о чем решь и никогда в этом не запутается.
Кончайте подводить высшую математику туда где ее нет и где она на фиг не упала.
... << RSDN@Home 1.2.0 alpha rev. 591>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Ой, а может поделишся как ты это делашь?
Выбираю в меню стулии Debug\Start включив до того Native Code Debugging. Что-то я не понял чему ты так удивляешь. Как будто отладкой никогда не занимался
Здравствуйте, VladD2, Вы писали:
VD>Это видимо такая неуклюжая попытка сохранить хорошую мину при плохой игре. Мол переход на личности и все такое. Не признавать, же что ничего не смотрел?
Да нет, я понял о чём я говорил и это не совсем то о чём говорил ты. Вобщем код ниже аналогичен использованию StringBuilder.Append гораздо медленнее его, не оптимизируется никаким C# компилятором и может быть оптимизирован за счёт перегрузки операторов (без изменения того куска кода который я привёл, разве что тип будет уже не string).
string a = "qwerty";
a += "asdfgh";
a += "asdfgh";
a += "asdfgh";
a += "asdfgh";