Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Здравствуйте, Serginio1, Вы писали:
S>>>>>>Если объекты создаются из разных DLL пусть это даже будут копии, то это уже будут разные типы. И при передаче параметра будет вызвано исключение. EP>>>>>Какого параметра? S>>>> У класса есть методы, у метода есть параметры, в том числе и out EP>>>Если у параметра тип который даёт единый ABI интерфейс для разных версий — то никаких проблем не будет. S>>Воо теперь нужно сравнивать не только тип, но и его эквивалентность
EP>Я говорю не про сами типы, а про интерфейсы.
А при чем здесь интерфейсы? Ааааах да в DLL то с классами проблема из-за версионности. А в Net есть GAC.
S>>>>>>Кроме того в двух DLL могут быть разные версии класса, что приводит к повреждению памяти. EP>>>>>Из-за чего? EP>>>>>Объекты могут быть разных версий, иметь разные менеджеры памяти, и при этом прекрасно сочетаться друг с другом S>>>> А обращаться к несуществующим полям, или массивам меньшей длины? EP>>>Проблемы будут есть вызывать методы одного класса на объекте другого. Если методы виртуальные и интерфейсы не поменялись, или вообще динамические а-ля Invoke — то проблемы не будет. S>> У тебя расположение полей может быть другое.
EP>И что? К ним доступ напрямую не осуществляется, только через виртуальную таблицу.
А в Net можно и без VMT и со статическими методами.
EP>>>Если же у тебя в голове какой-то use-case, в котором метод одного класса вызывается на объекте другого класса — то так и опиши его, я мысли читать не умею. S>> А как ты понимаешь обращение к полям, вызов метода. Смещение полей, методов может меняться.
EP>Ни смещение полей, ни методов, роли не играет пока мы к ним не обращаемся напрямую. Также не играет роли sizeof пока мы сами не создаём объекты.
А как мы должны обращаться к методам класса? В Net за соответствие типов отвечает среда выполнения.
S>>Даже VMT и та может поменяться. Да и методы могут в реалии иметь другую сигнатуру.
EP>Это уже изменение интерфейса.
А они имеют свойства меняться. В Com эта проблема решенная в Net EP>>>Про деревья нашёл вот тут — то есть правка уже после того как я прочитал и начал отвечать. Ты если делаешь существенные правки — выноси их в отдельные сообщения S>>Про валуе типы я подправил. А вот то, что полями могут быть экземпляры классов, как раз и говорит о деревьях. S>>Так как полей объектов тоже могут быть поля объекты.
EP>И что из этого?
EP>>>Подсчёт ссылок есть у враппера — он предоставляет AddRef/Release, которые должен дёргать клиент в соответствии с протоколом COM. EP>>>Если например запрашивается свойство не примитивного типа — возвращается новый враппер, при этом если у этого свойства в оригинале нет своего подсчёта ссылок, то будет использоваться счётчик агрегирующего объекта. S>> Подсчет ссыло врапера не спасает, от того, что тебе нужно либо считать ссылки на объект, либо перед удалением искать ссылки во враперах
EP>Подробнее.
Подробнее не времени. Ссылки на объект могут быть как из враперов (а их может быть несколько если они не кэшируются), так и внутри объектов.
Нужен подсчет ссылок объекта
S>>>>>>Ну и конечно твой нелюбимый GC EP>>>>>Почему нелюбимый? Без проблем использую языки с GC, о чём тебе лично уже пару раз сказал. Я даже как-то делал копирующий GC for fun. EP>>>>>Да и причём тут GC? S>>>> А то, что не нужен подсчет ссылок в объекте. GC сам ведет подсчет. EP>>>Счётчик должен быть внутри компонента, это базовый интерфейс — IUnknown. То что конкретные клиенты могут вызывать AddRef/Release на основе разных подходов — дело десятое, и не снимает необходимости в вызове этих AddRef/Release S>> То есть в С++ все классы реализуют IUnknown с автоматическим AddRef/Release? S>>Такого даже в Delphi нет.
EP>Ещё раз, они реализуются неинтрузивно, тем более когда речь идёт о враппере под IDispatch.
Блин а русских словей у тебя нет?
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, alex_public, Вы писали:
_>Здравствуйте, Serginio1, Вы писали:
S>> Еще раз моя обертка для любого нетовского класса, который 1С ник может использовать только зная имя класса если сборка загружена либо AssemblyQualifiedName S>>если сборка находится в GAC.
_>Ну так а для использования из 1C C++ кода, сделанного с поддержкой COM'a даже и никакие обёртки не нужны.
А вот мне не нужна поддержка ком любого нетовского класса. Это уже издевательство какое то.
S>>>> Это еще раз подтверждение того, что ты невнимательно читаешь ссылки _>>>Эээ что? ) S>> То, что привел пример универсальной обертки. Где не нужно делать каких либо действий, кроме подписки на события. S>>Это плюсы Net, где есть Reflection, заглушка к COM, GC. Чего нет в C++. А решать все через предварительное создание враперов не выход, так как я не знаю, чего захочет 1С ник (какие классы, сборки будет использовать), так как врапер универсальный и в real time. По сути это бесплатное расширение 1С. Но самый смех в том, что это мало кому нужно.
_>Вообще то мы сравнивали сложность написания C# и C++ кода, который потом будут вызывать из 1C. Так вот в этом разницы не видно. Если же ты хочешь поговорить о возможности запуска из 1C некого чужого, скомпилированного в бинарник кода, то это уже совсем другой вопрос для другой дискуссии.
Да написания C# кода вообще не существует. Используются любые нетовские классы.
Так запускается то скомпилированный код сборки. Ну читайте внимательно о чем речь. Вы же С++ ники белая кость.
public object CreateObject(object type)
{
var res = ТипДляСоздатьОбъект(type);
return AutoWrap.ОбернутьОбъект(System.Activator.CreateInstance(res));
}
public object СоздатьОбъект(object Тип, params object[] argOrig)
{
// MessageBox.Show(Тип.ToString() + " параметров=" + args.Length.ToString());var res = ТипДляСоздатьОбъект(Тип);
object[] args = AutoWrap.ПолучитьМассивРеальныхОбъектов(argOrig);
return AutoWrap.ОбернутьОбъект(System.Activator.CreateInstance(res, args));
}
Создает экземпляр указанного типа, используя конструктор, соответствующий заданным параметрам.
Кстати в Net 4.5 появилась поддержка для Com params object[]
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Serginio1, Вы писали:
S>>>>> Кстати а чем С++ хуже питона, раз питон используется с С++? S>>>>>C# точно ничем не хуже. EP>>C# менее гибкий для обобщённого кода. Например EP>>Python: EP>>C++: EP>>C#?
S>https://msdn.microsoft.com/ru-ru/library/39bb81c3.aspx
И как это относится к примеру?
S>Ну и джененрики интефейсы
Покажи код.
EP>>3. Всякие скрипты для личных нужд, работа с файлами, построение графиков, символьные вычисления и т.п. S> То есть, что не удобно делать на С++.
Почему по-твоему не удобно?
S> Вот а в C# практически все в одном.
Здравствуйте, Evgeny.Panasyuk, Вы писали:
I>>>>Браво, капитан, глубина не изменится, потому что граф объектов будет тем же самым. EP>>>Значит весь оверхед от случаев где ref-counting это исключительно подстраховка — это inc/dec (которых на C++11 существенно меньше). О чём я и говорил I>> Алё, я эти издержки вообще не считаю. На кой ляд ты доказываешь мне, что они ничтожны ?
EP>В этом случае других издержек нет
Здравствуйте, Serginio1, Вы писали:
S>>>>>>>Кроме того в двух DLL могут быть разные версии класса, что приводит к повреждению памяти. EP>>>>>>Из-за чего? EP>>>>>>Объекты могут быть разных версий, иметь разные менеджеры памяти, и при этом прекрасно сочетаться друг с другом S>>>>> А обращаться к несуществующим полям, или массивам меньшей длины? EP>>>>Проблемы будут есть вызывать методы одного класса на объекте другого. Если методы виртуальные и интерфейсы не поменялись, или вообще динамические а-ля Invoke — то проблемы не будет. S>>> У тебя расположение полей может быть другое. EP>>И что? К ним доступ напрямую не осуществляется, только через виртуальную таблицу. S> А в Net можно и без VMT и со статическими методами.
Минуя COM?
EP>>>>Если же у тебя в голове какой-то use-case, в котором метод одного класса вызывается на объекте другого класса — то так и опиши его, я мысли читать не умею. S>>> А как ты понимаешь обращение к полям, вызов метода. Смещение полей, методов может меняться. EP>>Ни смещение полей, ни методов, роли не играет пока мы к ним не обращаемся напрямую. Также не играет роли sizeof пока мы сами не создаём объекты. S> А как мы должны обращаться к методам класса? В Net за соответствие типов отвечает среда выполнения.
Если речь идёт про COM, то через виртуальную таблицу, а её layout зависит от интерфейса.
EP>>>>Подсчёт ссылок есть у враппера — он предоставляет AddRef/Release, которые должен дёргать клиент в соответствии с протоколом COM. EP>>>>Если например запрашивается свойство не примитивного типа — возвращается новый враппер, при этом если у этого свойства в оригинале нет своего подсчёта ссылок, то будет использоваться счётчик агрегирующего объекта. S>>> Подсчет ссыло врапера не спасает, от того, что тебе нужно либо считать ссылки на объект, либо перед удалением искать ссылки во враперах EP>>Подробнее. S> Подробнее не времени. Ссылки на объект могут быть как из враперов (а их может быть несколько если они не кэшируются), так и внутри объектов. S>Нужен подсчет ссылок объекта
Проблема в чём?
EP>>>>Счётчик должен быть внутри компонента, это базовый интерфейс — IUnknown. То что конкретные клиенты могут вызывать AddRef/Release на основе разных подходов — дело десятое, и не снимает необходимости в вызове этих AddRef/Release S>>> То есть в С++ все классы реализуют IUnknown с автоматическим AddRef/Release? S>>>Такого даже в Delphi нет. EP>>Ещё раз, они реализуются неинтрузивно, тем более когда речь идёт о враппере под IDispatch. S>Блин а русских словей у тебя нет?
"неинтрузивно" — то есть не меняя сам класс. Счётчик ссылок, также как и вся кухня Invoke/etc, будет во враппере.
Здравствуйте, ·, Вы писали:
I>>Все эти вещи когда то писали на Си/С++. Питон, перл, пхп — все это выстрелило уже после того, как С++ оттуда ушел. ·>Что-то сомневаюсь. C ещё может быть, С++ — очень вряд ли. Но С просто старше. А уж LAMP всегда был классикой. Веб на С — это либо экзотика, либо старьё.
Смешно. "всегда" началось совсем недавно, от силы 10 лет назад.
I>>·>Наравне с Java. I>>Джава в роли догоняющего. ·>Примерно как С++ догоняет Кобол.
Кобол в HFT ? Пудозреваю, исключительно за счет С++.
I>>·>Да какая архитектура блин. Вместо "MyObj obj = new MyObj()" пишешь "MyObj obj = newMyObj()", в общем-то и вся разница по факту. I>>По факту запрещено многие вещи вызывать именно из за этого ограничения. ·>Что запрещено? Не понял мысль.
Сам подумай — как ты заюзаешь чужую либу, если она не в курсе про твои ограничения `newMyObj` вместо `new MyObj`.
Она рассчитывает на GC, а у тебя нужно явно всё освобождать и тд.
Здравствуйте, Ikemefula, Вы писали:
I>>>>>Браво, капитан, глубина не изменится, потому что граф объектов будет тем же самым. EP>>>>Значит весь оверхед от случаев где ref-counting это исключительно подстраховка — это inc/dec (которых на C++11 существенно меньше). О чём я и говорил I>>> Алё, я эти издержки вообще не считаю. На кой ляд ты доказываешь мне, что они ничтожны ? EP>>В этом случае других издержек нет I>Ну да, а граф объектов разрушится за время 0.
Он разрушался бы даже если убрать этот ref-counting, который был лишь исключительно для подстраховки (а речь именно об этом случае).
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Здравствуйте, Serginio1, Вы писали:
S>>>>>> Кстати а чем С++ хуже питона, раз питон используется с С++? S>>>>>>C# точно ничем не хуже. EP>>>C# менее гибкий для обобщённого кода. Например EP>>>Python: EP>>>C++: EP>>>C#?
S>>https://msdn.microsoft.com/ru-ru/library/39bb81c3.aspx
EP>И как это относится к примеру? https://msdn.microsoft.com/ru-ru/library/s53ehcz3.aspx
Я могу через рефлекшн вызвать соответствующие методы. https://msdn.microsoft.com/ru-RU/library/system.datetime.op_addition(v=vs.71).aspx S>>Ну и джененрики интефейсы
EP>Покажи код.
Нет времени. EP>>>3. Всякие скрипты для личных нужд, работа с файлами, построение графиков, символьные вычисления и т.п. S>> То есть, что не удобно делать на С++.
EP>Почему по-твоему не удобно?
S>> Вот а в C# практически все в одном.
EP>Язык менее гибкий чем Python. А плюсы-то какие?
Это с чего это менее гибкий?
То есть ты плюсов не видишь? Я потратил кучу времени, а ты даже плюсов не нашел. Смысл в разговоре?
и солнце б утром не вставало, когда бы не было меня
S>>>> У тебя расположение полей может быть другое. EP>>>И что? К ним доступ напрямую не осуществляется, только через виртуальную таблицу. S>> А в Net можно и без VMT и со статическими методами.
EP>Минуя COM?
Да EP>>>>>Если же у тебя в голове какой-то use-case, в котором метод одного класса вызывается на объекте другого класса — то так и опиши его, я мысли читать не умею. S>>>> А как ты понимаешь обращение к полям, вызов метода. Смещение полей, методов может меняться. EP>>>Ни смещение полей, ни методов, роли не играет пока мы к ним не обращаемся напрямую. Также не играет роли sizeof пока мы сами не создаём объекты. S>> А как мы должны обращаться к методам класса? В Net за соответствие типов отвечает среда выполнения.
EP>Если речь идёт про COM, то через виртуальную таблицу, а её layout зависит от интерфейса.
Вообще то речь идет про доступ к С++ и .Net объектам через Idispatch.
Ghb 'njv j,]trns vjuen gthtlfdfnmcz bp hfpys[ ВДД
EP>>>>>Подсчёт ссылок есть у враппера — он предоставляет AddRef/Release, которые должен дёргать клиент в соответствии с протоколом COM. EP>>>>>Если например запрашивается свойство не примитивного типа — возвращается новый враппер, при этом если у этого свойства в оригинале нет своего подсчёта ссылок, то будет использоваться счётчик агрегирующего объекта. S>>>> Подсчет ссыло врапера не спасает, от того, что тебе нужно либо считать ссылки на объект, либо перед удалением искать ссылки во враперах EP>>>Подробнее. S>> Подробнее не времени. Ссылки на объект могут быть как из враперов (а их может быть несколько если они не кэшируются), так и внутри объектов. S>>Нужен подсчет ссылок объекта
EP>Проблема в чём?
У тебя нет проблем.Ты даже ни одного примера с полями объектами не привел. EP>>>>>Счётчик должен быть внутри компонента, это базовый интерфейс — IUnknown. То что конкретные клиенты могут вызывать AddRef/Release на основе разных подходов — дело десятое, и не снимает необходимости в вызове этих AddRef/Release S>>>> То есть в С++ все классы реализуют IUnknown с автоматическим AddRef/Release? S>>>>Такого даже в Delphi нет. EP>>>Ещё раз, они реализуются неинтрузивно, тем более когда речь идёт о враппере под IDispatch. S>>Блин а русских словей у тебя нет?
EP>"неинтрузивно" — то есть не меняя сам класс. Счётчик ссылок, также как и вся кухня Invoke/etc, будет во враппере.
Ну дык он должен поменяться не только для врапера но и везде где используется
и солнце б утром не вставало, когда бы не было меня
Да причём тут это? Пример про простую функцию высшего порядка apply — на Python и C++ она элементарно реализуется. Покажи аналог на C#.
S>>>Ну и джененрики интефейсы EP>>Покажи код. S> Нет времени.
Необязательно прям сейчас.
S>>> Вот а в C# практически все в одном. EP>>Язык менее гибкий чем Python. А плюсы-то какие? S> Это с чего это менее гибкий?
Покажи пример с apply — на нём видно как раз.
S>То есть ты плюсов не видишь? Я потратил кучу времени, а ты даже плюсов не нашел. Смысл в разговоре?
Какие плюсы у C# перед Python примирительно к скриптам?
Здравствуйте, Serginio1, Вы писали:
S>>>>> У тебя расположение полей может быть другое. EP>>>>И что? К ним доступ напрямую не осуществляется, только через виртуальную таблицу. S>>> А в Net можно и без VMT и со статическими методами. EP>>Минуя COM? S> Да
И к чему это? Речь-то шла про COM
EP>>>>>>Счётчик должен быть внутри компонента, это базовый интерфейс — IUnknown. То что конкретные клиенты могут вызывать AddRef/Release на основе разных подходов — дело десятое, и не снимает необходимости в вызове этих AddRef/Release S>>>>> То есть в С++ все классы реализуют IUnknown с автоматическим AddRef/Release? S>>>>>Такого даже в Delphi нет. EP>>>>Ещё раз, они реализуются неинтрузивно, тем более когда речь идёт о враппере под IDispatch. S>>>Блин а русских словей у тебя нет? EP>>"неинтрузивно" — то есть не меняя сам класс. Счётчик ссылок, также как и вся кухня Invoke/etc, будет во враппере. S> Ну дык он должен поменяться не только для врапера но и везде где используется
Здравствуйте, Evgeny.Panasyuk, Вы писали:
I>>Ну да, а граф объектов разрушится за время 0.
EP>Он разрушался бы даже если убрать этот ref-counting, который был лишь исключительно для подстраховки (а речь именно об этом случае).
Здравствуйте, alex_public, Вы писали:
_>А ты их сам сравнивал? ) Я вот сравнивал и MSVS и Eclipse и Netbeans и QtCreator. MSVC кстати весьма слабенький для C++, если не пользоваться VisualAssist'ом (отдельная платная штука). Eclipse и Netbeans весьма похожи между собой по возможностям и при этом существенно отличаются от того же QtCreator. У них используется модель полного анализа кода, которая позволяет такую возможность как подчёркивать невалидный код до компиляции и т.п.. Но цена у этого жуткие тормоза. Ну точнее если работать только с ними, то постепенно привыкаешь к тормознутости IDE... Но если вдруг при этом включить QtCreator, то такое впечатление что он просто мгновенный. Но при этом он делает не полный анализ кода... В принципе выбор между этими продуктами является делом вкуса. Но говорить о явном преимуществ какой-то из них странно.
QtCreator проще тем, что это только С++ и больше ничего. Другие IDE — это целая платформа с кучей расширений и плагинов.
_>Кстати, недавно одному моему товарищу, работающему в основном в мире Java, потребовалось сделать приложение с GUI на C++. Он взял библиотеку Qt (по моему совету) и соответственно QtCreator в качестве IDE (ради удобного встроенного редактора форм/сигналов и т.п.). Так вот он был в полном восторге (особенно от всяческих автоматических компоновщиков и их поддержке в редакторе, управлением сигналами и т.п.) от этого инструмента (накидал довольно сложный GUI за несколько дней), причём во многом он удивлялся что так вообще можно (в своём java мире он такого не встречал).
Java в GUI не самая лучшая, родные средства довольно убогие и устаревшие. Надо было хотя бы c# взять, правда оно win-only.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, alex_public, Вы писали:
_>>>Undefined behaviour это по стандарту языка, без учёта работы ОС. Ну т.е. да, для каких-нибудь микроконтроллеров там действительно будет порча памяти, но на этих МК такие вещи как Java/C# вообще не живут. А в любой современной ОС мы получим соответствующее исключение. _>·>Т.е. ты даже в двух строчках кода забыл "x=nullptr"... А в случае более-менее сложного кода, да ещё и многопоточного — только в путь. _>Ну так у меня же мало практики в написание заведомо некорректного кода. Я вообще сам delete раз год вижу, даже с корректным кодом. А тут такое... )))
Ты написал его типично. Чаще так оно и происходит. Время жизни в одном месте, удаление в другом месте, добавленное в другое время, другим девом в другом потоке.
_>·>И ты правда не видел битых указателях в реальных проектах? Укажи, плиз, номер твоей планеты в тентуре. _>В своих, ушедших в продакшен, — не видел. )
А сколько девов принимало участие? Сколько человеколет? Если меньше 5 девов, менее сотни человеколет, то это мелкие проекты... Их хоть на ассемблере пиши, не принципиально.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, alex_public, Вы писали:
_>>>Дефолтное — это value type и контейнеры stl. Есть парочка редких случаев, когда применение этих инструментов приводит к не самому оптимальному кода (и тогда как раз делают всяческие кастомные аллокаторы и т.п.), но лично я на них натыкался исключительно в обсуждениях на форумах и т.п., а не в личной практике. _>·>В дефолтном случае и GC замечательно работает. А вот эти обсуждаемые извращения в Яве это и есть те самые редкие случаи. _>Нет, это как раз совсем разные случаи. Единственный сценарий, на котором GC начинает конкурировать с обычной работой с памятью в C++ — это режим создания/удаления множества мелких объектов в куче. Так вот этот режим в C++ встречается на очень редком классе задач (и для них уже есть смысл рассматривать спец. аллокаторы и т.п.). И задачи типа реалтайма или высокой нагрузки точно не относятся к этому исключению — там как раз эффективны стандартные техники C++.
Говорю же — два режима оптимальны. Второй режим — объекты создаются и уничтожаются редко. Редко меняется граф объектов в памяти. (т.е. топология графа не меняется, но данные внутри объектов меняться могут).
Неоптимальный режим — создали кучу объектов, помариновали их какое-то время и потом грохаем.
_>В то же время в Java режим создания/удаления множества мелких объектов в куче — это норма. И хотя GC не так плохо справляется тут, но он намного отстаёт от C++ на большинстве задач, т.к. в C++ в этих случаях используется другой режим (который априори быстрее). И только в том случае, когда и в C++ необходимо плодить сущности типа shared_ptr, быстродействие может сравниться (при условие, что в C++ не будем вводить кастомные извращения). _>Соответственно, чтобы догнать C++ на задачах реалтайма, высокой нагрузки и т.п. (в остальных областях тоже медленно, но всем просто пофиг) в Java переходят от дефолтного режима на некое извращение с рукопашными буферами и т.п. ужасами для эмуляции стандартных техник C++.
Собственно и в плюсах ты переходишь от комфортного by-value/on stack к хитрым аллокаторам, жонглированию различными типами указателей, повышая риск что-то поломать или потерять.
_>Т.е. главный нюанс в том, что хотя в обоих языках есть области, требующие неких нестандартных для языка подходов, эти области совершенно разные у данных языков. И размеры этих областей тоже принципиально разные.
Собственно в LL-системе "плохая" часть очень маленькая. Только из малой области кода выжимаются все соки, а остальное пишется как обычно, с комфортом GC.
_>>>·>А ты часто обдумываешь в какие регистры процессора какая переменная попадёт? _>>>Совершенно не обдумываю, причём по разным причинам в двух разных случаях. В случае отсутствия необходимости в быстродействие (кстати в этом случае у меня скорее Питон в руках будет) понятно что не обдумываю потому что безразлично. А в случае необходимости высокого быстродействия и использования C++ тоже не обдумываю, потому как знаю, что оптимизатор современных компиляторов C++ создаст код лучше любого эксперта в ассемблере. _>·>Собственно та же ситуация и с GC. _>Абсолютно не такая же. Напомню, что мы здесь обсуждали возможности JIT выбрать расположение и типы данных (куча/стек, ссылка/значение и т.д.) наиболее оптимальным способом. И в отличие от качества генерирования ассемблерного кода оптимизаторами C++, тут ситуация даже не приблизилась к идеалу. И я сомневаюсь что приблизится когда-нибудь, т.к. тут задача намного сложнее.
Принципиально — для JIT оптимизаций доступно гораздо больше информации, т.к. оно работает во время испонения. И оптимизация происходит именно в соответствии с реальной нагрузкой. Есть, конечно Profile Guided Optimisation, но она, насколько я знаю, представляет в основном академиеческий интерес.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, alex_public, Вы писали:
_>>>Лично я не увидел в этом списке чего-то необычного, заставившего писать непривычный код. _>·>А тебе вообще доводилось писать LL код? _>Я же тебе уже даже примеры приводил. ) И да, оно не из области финансов. )))
В смысле видео|игры?
_>·>В ФФ бОльшая пользовательская часть это js, xul и прочее. А вообще браузер системная вещь — основное назначение — взаимодействие с железом и ОС. Не путай с прикладными приложениями, типа очередной бухгалтерии или склада. _>Да, написание приложения на C++ со встроенным скриптовым языком — это стандартная техника написания сложных и эффективных приложений. Это не только браузеры, но и тяжёлые игры и всякий профессиональный софт (CAD'ы, редакторы/рендереры и т.п.)и ещё много где. Проще вспомнить где такого нет. ))) Кстати, мы такое тоже используем.
Вот и считай... что java это такой встроенный скриптовый язык для решения прикладных задач — обработать 20000 заявок в секунду. И нет такой прикладной задачи "разместить структуру данных в памяти последовательно с минимумом индирекций".
_>Да, и браузер — это совсем не системный софт (с каких это пор взаимодействие с ОС стало признаком системного софта?), т.к. работает на обычном пользовательском уровне. Системный софт — это всяческие драйверы, сервисы и т.п. )
Браузер не решает _прикладные_ задачи (т.е. задача непосредственно решаемая конечным пользователем). Прикладная задача — читать емейл, инвестировать деньги, купить беззеркалку, поставить лайк. А рендер html/css, выполнение js — это не прикладные задачи. И, что характерно, всякие прикладные вещи в браузере типа управление списком скачанных файлов, диалоги настроек и т.п — пишется на js/xul.
_>>>Так а зачем я тогда буду делать такой MaClass? ))) Кстати, куча полей — это сколько? ) Ты в курсе размера линии кэша современных процессоров? ) _>·>"Дефолтное — это value type и контейнеры stl" и даст тебе тот самый жирный MyClass. _>·>Кеш в районе всего лишь нескольких мегабайт — копейки же, миллиончик элементов — и упс, кончилось. _>Хыхы, в данном случае важнее размер не всего кэша, а именно его линий (в соотношение с размером самого объекта). А так же очевидная для предсказателя последовательность выборки.
Линия вроде вообще 64 байта или что-то типа того. Или я с чем-то путаю?
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, Serginio1, Вы писали:
S>Со свойствами проблема, но их можно динамически обернуть. То есть сделать обертку над классом для описания свойв. S>Для простых случаев можно так. S>[cs] S> [ComVisible(true)] S> [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] S> // [Guid("33B45C9D-1AED-41F9-8880-36AB6AE84749")] S> public interface IEventFor1C
S> Либо пишу ручками используя анонимные типы. И подписка
Не понял, для каких простых случаев, какими ручками? Ты же оборачиваешь произвольную .NET сборку в COM.
Если не поможет, будем действовать током... 600 Вольт (C)
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>>>А зачем человеку доказывать? Например: EP>>>Результат может содержать ссылку на этот unique, а может не содержать. Человек может например просто знать из документации что в результирующем объекте нет этого unique. dot>>Тут мне кто-то рассказывал, что надо голые указатели использовать при передаче между потоками. EP>Для не владеющих указателей — да. Здесь речь идёт про владеющий. Да и к чему ты тему переводишь?
Довольно нетривиально доказать кто чем владеет. Тем более в развивающемся проекте.
EP>>>Анализатору же придётся это доказывать проинлайнив весь код. dot>>Да пусть доказывает, он железный, зарплату не просит. EP>У него есть жёсткие ограничения по бюджету времени — так как работает у конечных пользователей.
Так ему, в отличие от плюсов, не надо это доказывать для каждого кусочка кода, а только для активно выполняемого.
EP>>>Это изменение контракта, которое прекрасно выражается в системе типов — у doSomething поменяется тип параметра и приведённый код не скомпилируется dot>>Поменяется с чего на что? как было (Widget &w) так и останется, если не лепить _ptr на каждый чих. EP>Теперь ей требуется владение — так как есть передача куда-то что может жить дольше caller'а. Вот тут как раз будет либо *_ptr, либо например rv ref — и то и другое приведёт к ошибке компиляции в старом клиентском коде
В момент внесения изменения было очевидно, что он не может быть дольше. А вот в процессе десятка других изменений, растянутых во времени, да и при стечении обстоятельств — вдруг пережило чуть дольше, чем предполагалось изначально.
dot>>При сборке Eden Space оно и грохнется, EP>Оно бы грохнулось в тот же самый момент и без EA.
Да, ты похоже прав. EA лишь позволяет грохать сразу когда что-то перенесётся из кучи в стек|регистры, а это вряд ли произойдёт для больших массивов. А большие массивы просто будут грохаться прямо в Eden. Т.е. ArrayList может оказаться на стеке, а сам большой Object[] будет в куче. Оптимизация будет скорее в том, что вместо общего аллокатора будет использован Thread Local Allocaiton Buffer.
А Object[] может грохаться только если оптимизатор поймёт, что размер его маленький и его можно разместить на стеке.
Разница может быть заметна, если у тебя этот vector возвращается по значению из функции и его размер большой, что передачу by-value сделает неэффективой. А значит ты должен будешь его в unique_ptr обернуть или надеяться на RVO.
dot>>не совсем при выходе из стека, но очень близко. EP>То есть совсем не при выходе из стэка. dot>>А если ты чуть поменяешь код и ссылка будет отправлена куда-то ещё, другому треду, попадёт в какой-нибудь контейнер, кеш, етс, то ничего не поломается, в отличие от unique_ptr. EP>У него тоже ничего не поломается. Даже если бы это был просто vector<T>, без unique_ptr — то тоже ничего бы не поломалось
Это если голые указатели не использовать.
dot>>>>Указатель ещё тип имеет. Ссылка в яве тоже адрес хранит и чё. EP>>>Конечно, и в типе разница — на C++ можно иметь указатель на элемент массива, на Java — нет. dot>>Ты так говоришь, как будто это что-то плохое. EP>Это очевидный недостаток. Например есть текст, нужно передать куда-то отдельный абзац — на C++ достаточно например либо двух указателей, либо указателя и числа символов, либо просто указателя на начало абзаца. На Java же придётся ещё таскать ссылку на сам текст.
В общем да, есть такое. Хотя далеко не факт, что это может стать какой-либо проблемой... В типичном приложении у тебя скорее всего будет ссылка на какой-нибудь Document, по которому можно найти его текст. Поэтому будет достаточно пары индексов. А в большинстве случаев помещение двух или трёх чисел на стек — погоды не делает.
EP>>>>>Например для Buddy Allocation сложность логарифмическая. Есть же в том числе и O(1) алгоритмы, например TLSF. dot>>>>Так и разные алгоритмы GC есть. И столько всего можно крутить... И я уверен, что вариантов даже больше, ибо ссылка в jvm более абстрактна чем указатели в плюсах, а значит больше простора для оптимизаций. EP>>>Так вот покажи GC не с сублинейной сложностью, желательно ещё чтобы был более-менее популярен. dot>>Если вдруг GC начинает работать в режиме, что его сложность становится O(N) — ты делаешь что-то не то, тебе надо крутить настройки или даже изменять код. EP>Нет гарантии что она завтра вдруг не выстрелит
А где ты берёшь гарантию, что какая-нибудь фрагментация кучи или битая ссылка не выстрелит?
dot>>>>Да, неудачный пример. Лучше рассмотреть hashtable. Сложность O(n). и что? Просто крутят использование до тех пор пока не станет почти O(1). Примерно так и с GC. EP>>>Штуки типа cuckoo hashing не на ровном месте появились. dot>>Не понял, оно worst case (не путаем с amortised) не меняет же вроде, так же O(n). EP>Меняет — поиск и удаление константы в худшем случае.
А добавление?
dot>>Так и gc не лыком шиты. EP>И что? Это меняет их сложность?
Нет. Но на практике, если GC начинает работать в worst case режиме, т.е. с O(n), приложение просто не используют. Скорее всего JVM тупо самоубьётся. Такое происходит на порядки реже, чем битые ссылки в плюсах.
dot>>>>Не смертельно. EP>>>Отдельный код для каждой комбинации. Конечно не смертельно, можно и на ASM'е писать рабочий код. dot>>Комбинации чего? EP>Структура данных * контейнер * алгоритм * etc. ЕМНИП даже в C# для разных структур generic даёт разные воплощения.
Круто, конечно. Но в горячем коде таких комбинаций обычно единицы. А остальному коду это всё не важно.
dot>>Сколько их? (только практику плз, а не теоретические рассуждения) EP>Очень много, это практика, реальный код. EP>Например вызвал сортировку для вектора со своим замыканием-предикатом — получил отдельный код оптимизированный конкретно под эту комбинацию.
Не факт, что это принесёт хоть какую-то пользу. compile time же.
dot>>Если можно было бы — писали бы и на асме, в LL все средства идут в ход. EP>Вряд ли получится ASM лучше того что даст C++, за какое-нибудь разумное время. Интринсинки — да, полезны, но это не ASM.
Естественно. Если получилось бы — использовали бы.
dot>>>>Это какие-то очень экзотические условия, у меня не получается представить когда в ссылочном дереве лишняя индирекция может стать серьёзной проблемой. EP>>>А например в хэш-таблице? dot>>Если значение большое, то индирекция нужна, иначе сам массив хеш-таблицы будет слишком большим и не помещаться в кеш. EP>1. Если малое — то уж точно не нужна, тут разногласия нет. EP>2. В описываемой тобой схеме получается: сначала latency на cache hit (пусть и небольшая) для того чтобы достать ссылку, потом latency на cache miss/поход в RAM, плюс кэш забивается лишними указателями, что снижает эффективность. Если же убрать индерекцию — то получается сразу поход в RAM, который есть и твоей схеме EP>3. Ключ может хранится отдельно от значения, причём без индерекции.
Указатель это 8 байт. Если указуемое больше — то уже индирекция может помочь съэкономить на объёме горячей структуры.
dot>>Если значение маленькое, то это скорее всего будет примитив. EP>С чего бы это?
Потому что примитив это те же 8 байт, что уже не так уж мало.
Самый неудобный случай если значение, скажем 10 байт... Т.е. как бы и в примитив никак не влазит и индирекцию делать неразумно. В этом случае требуется извращение.
Но по-моему обычно либо что-то маленькое — значение влазит в 8 байт, либо большое, сотни байт.
EP>>>В случае с GC что будешь делать? dot>>Подстрою GC. EP>Подстройка называется GC-free/off-heap , да?
В большинстве случаев достаточно покрутить параметры самого gc — интервалы сборки, размеры поколений, етс.
dot>>Элементы — пусть лежат, если ты не создаёшь|удаляешь их постоянно, а просто меняешь их поля — GC вообще не парится. GC ведёт себя плохо если постоянно меняется граф объектов долго лежащих в памяти. EP>Если короче, то вот это утверждение неверное: EP>
dot>>Так в этих же случаях и в яве всё будет всё в YG, а значит никакого жуткого O(N).
По приведённому тобой случаю вообще непонятно что там происходит. Если там просто данные меняются, то да, не будет O(n), а если объекты среднеживущие и постоянно всё жутко перетасовывается, то да — gc будет тормозить.
dot>>Собственно это соответствует сложному жонглированию владением в C++, EP>Не сложному, и не соответствует. Большинство случаев владения (и "жонглирования" им) C++ это простейший by-value.
by-value будет тупой YG, говорю же: зашли в функцию, создали объект, передали в глубь, там ещё что-то насоздавалось, там ещё глубже, пару циклов... а потом вышли и всё грохнули из YG пачкой.
dot>>где это запросто приведёт к битым указателям, если у вас в команде не Александреску с Страуструпом под руководством Кнута. EP>"Запросто" не приведёт. А вот valgrind запросто отловит.
В многопоточном?.. Может отловит, может и не отловит...
EP>>>Конечно будет, и это одна из причин почему положит на лопатки.EP>>>Именно так и происходит
в Emscripten, который компилирует C++ в JS. EP>>>И JS кстати получается реально быстрый. На одном из тестов работает практически в два раза быстрее чем аналогичный код на C#. JS, в веб-браузере, Карл! И этом при том что в C# версии были структуры. Если же брать аналогичный код на Java — то всё будет ещё круче Можем кстати сравнить. dot>>Ну и кому эти микробенчмарки нужны? EP>Тем кого интересует скорость
Для написания статьей о скорости может и сгодиться. А на практике обычно надо чтобы оно что-то полезное делало, а не быстрое.
dot>>Ты давай пример системы на плюсах, компилированных под jvm. EP>Я не знаю нормального компилятора C++ -> JVM. Есть даже мысли за-proof-of-concept'ить такой.
Потому и не знаешь, что принципиально невозможно.
dot>>Как дойдёт до времени отклика или тупо многопоточности (как там многопоточность в JS, кстати?), то всё и станет на свои места. EP>Причём тут многопоточность JS? Какое время отклика? Ты о чём? Я мысли читать не умею.
Когда у тебя всё работает в одном потоке, то примерно почти все сложности с которыми сталкивается GC становятся не нужны. А значит и всё становится проще, и, естественно быстрее.
dot>>Кстати, это, конечно, очень субъективно, но когда я искал работу (London), я всегда писал Java/C++ и выбирал finance. И из ~сотни интерьвю не было ни одного С++. Выводы, конечно, можно сделать разные... но всё же. EP>Конечно субъективно — мне как раз оттуда приходили варианты C++, правда не finance, и я вообще не искал. И что характерно не было ни одной Java.
Мне тоже приходили... судя по всему анализируют резюме по ключевым словам и шлют ковровые рассылки, и зарплаты примерно в 2 раза меньше...
EP>>>>>Те же структуры есть в C#. dot>>>>А толку-то от них... EP>>>Не нужно вручную нарезать массивы на структуры dot>>И что это даёт? Что позволяет добиться? EP>Добиться меньшего количества низкоуровневого error-prone кода.
Ну и? Добились меньшего количества кода. А дальше что? И где же low latency C#-системы?
Ни один вменяемый заказчик не ставит цель "меньше кода". Цель — чтобы работало с указанными требованиями. Java, как показывает практика, работает и без стркутрур. Пусть кода чуть больше, но в целом система проще.
При наличии хорошей IDE количество кода практически ни на что не влияет. А простота кода, минимум конструкций — даёт много ништяков.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Здравствуйте, Serginio1, Вы писали:
S>>>>>> У тебя расположение полей может быть другое. EP>>>>>И что? К ним доступ напрямую не осуществляется, только через виртуальную таблицу. S>>>> А в Net можно и без VMT и со статическими методами. EP>>>Минуя COM? S>> Да
EP>И к чему это? Речь-то шла про COM
Речь шла про доступ к объектамчерез Idispatch.
Еще раз приведу ссылки
Я первоначальный вариант сделал за 15 минут. Раз это это элементарно сделайте и 1С ники будут вам благодарны EP>Он и для враппера не меняется.
Короче сделай раз это элементарно аналог по моим ссылкам.
У Net варианта есть минус в том, что должен установлен Net.
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, -MyXa-, Вы писали:
MX>Здравствуйте, Serginio1, Вы писали:
S>>Со свойствами проблема, но их можно динамически обернуть. То есть сделать обертку над классом для описания свойв. S>>Для простых случаев можно так. S>>
S>> [ComVisible(true)]
S>> [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
S>> // [Guid("33B45C9D-1AED-41F9-8880-36AB6AE84749")]
S>> public interface IEventFor1C
S>> Либо пишу ручками используя анонимные типы. И подписка
MX>Не понял, для каких простых случаев, какими ручками? Ты же оборачиваешь произвольную .NET сборку в COM.
Простых случаев это для методов без параметров и методом с параметром типа Object/
[code]
врап=новый COMОбъект("NetObjectToIDispatch45");
Сборка=врап.загрузитьСборку(ИмяФайлаСборки); //ПроектИспользованияДелегатов.dll
тип=Сборка.GetType("ПроектИспользованияДелегатов.КлассДляВнешнихСобытий");
ОбъектССобытием=врап.СоздатьОбъект(Тип,КаталогДляОтслеживанияИзменений);
Событие=Врап.ПолучитьОбъектДляСобытий(ОбъектССобытием,"Событие");
СобытиеПереименования=Врап.ПолучитьОбъектДляСобытий(ОбъектССобытием,"СобытиеПереименованияФайла");
ДобавитьОбработчик Событие.Событие, ПриИзмененииДиректории;
ДобавитьОбработчик СобытиеПереименования.Событие, ПриПереименованииФайла;
[/code]
Сам класс такой.
[cs]
public class КлассДляВнешнихСобытий
{
public string ИзмененныйФайл;
public string ПереименованныйФайл;
public event System.Action Событие;
public event System.Action СобытиеПереименованияФайла;
FileSystemWatcher watcher;
private void ИзмененияВДиректории(object source, FileSystemEventArgs e)
{
// Specify what is done when a file is changed, created, or deleted.
ИзмененныйФайл = e.FullPath + " " + e.ChangeType;
if (this.Событие != null) Событие();
}
public КлассДляВнешнихСобытий(string Директория)
{
watcher = new FileSystemWatcher();
watcher.Path = Директория;
/* Watch for changes in LastAccess and LastWrite times, and
the renaming of files or directories. */
watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
| NotifyFilters.FileName | NotifyFilters.DirectoryName;
// Only watch text files.
watcher.Filter = "*.*";
// Add event handlers.
watcher.Changed += new FileSystemEventHandler(ИзмененияВДиректории);
watcher.Created += new FileSystemEventHandler(ИзмененияВДиректории);
watcher.Deleted += new FileSystemEventHandler(ИзмененияВДиректории);
watcher.Renamed += new RenamedEventHandler(OnRenamed);
// Begin watching.
watcher.IncludeSubdirectories = true;
watcher.EnableRaisingEvents = true;
}
и солнце б утром не вставало, когда бы не было меня