Ru-Board.club
← Вернуться в раздел «Прикладное программирование»

» Вопросы по Embarcadero RAD Studio XE5-XE8,10.x(Seattle, Berl

Автор: AlekXL
Дата сообщения: 09.01.2015 21:31
kaz_av

Цитата:
Я вообще не предлагал ни каких сравнений, я рассказал о случае из практики

да ну?

Цитата:
Лично наблюдал, как код на жабе делающий огромное количество операций со строками драл аналогичный дельфийский и плюсовый код. Для паритета и на дельфях и на плюсах пришлось пользоваться собственным аллокатором под задачу

если это не сравнение, то что?

Я показал, что такой случай не показателен для действительно критического к производительности приложения.

Там если и есть преимущество, то только в весьма ограниченных рамках, и только потому, что работа с памятью вынесена в отдельный поток, потребляющий ресурсы дополнительно, а самой памяти нужно вдвое больше, чем дельфийскому или "плюсовому" приложению.
Сам GC концептуально и фактически медленнее ручного управления. Он дает большую безопасность, запрашивая при этом значительную цену.


Цитата:
Мой первоначальный оксидженовский код, будучи переписаным на использование статического стрингбилдера работает медленнее

Думаю, ты сделал что-то неправильно. Ну или оксиджен тупит.

Цитата:
Ты её не ограничил, а дал столько, чтоб при таком количестве данных система тебя в своп не загнала. А вот потребность GC ты ограничил. Это читерство в чистом виде.

ничего не понял...
Для Delphi это ограничение никак не сказывается: она и на 400 тысячах элементов не перекрывает в потреблении 400 метров.
Ну а своп JVM ее бы только замедлил.
Я смоделировал ситуацию ограниченных ресурсов, потому что ресурсы всегда ограничены.
И показал, что когда масштаб задачи подбирается, хотя бы даже и не вплотную, к потолку ресурсов системы, JVM sucks, тупит и лагает.
Какое же это читерство?

Мои выкладки, в отличие от твоих "впечатлений" и "случаев", объективны: я показал и превосходство JVM в одних случаях, и ее недостатки -- в других.
И сделал взвешенный, беспристрастный вывод -- Java малопригодна для случаев, когда теоретический размер и сложность задачи близок к актуальному пределу железа.

Пять лет назад оптимисты сказали бы: "ну и что, железо удваивает мощность каждые два-три года". Сегодня -- мы уже знаем, что это не работает. Производительность на такт, на ватт, на гигабайт памяти -- снова приобретает значимость.

И тут managed языкам приходится кисло.

Цитата:
Ты же перешел от любезностей к обвинениям, с чего мне себя сдерживать?

между обвинениями и оскорблениями есть разница. Жаль, что ты этого не улавливаешь.

Я поначалу думал, что ты просто заблуждаешься, когда ставить вровень managed языки и натив. Тогда я потратил время(это вообще первое мое приложение под java, так что усилие было значительным), и написал тестовое приложение на Java, аналогичное твоему.
Оптимизировал его: слачала ввел статический StringBuilder, а потом увеличил размер пула "молодых" объектов.
Каждый из этих двух шагов дает практически двукраное ускорение. Далее, провел исследование, достаточное, наверное, даже для статейки на хабре, выложил код. Показал силу и слабость JVM.

И тут ты начинаешь лепить отмазки: мол, "я только говорил о скорости, а о памяти ничего не говорил"... Что якобы я поставил JVM в "невыгодные условия", хотя условия для JVM были равными или превосходили условия для Delphi.

То есть ты упорствуешь, и говоришь как фанатик или евангелист managed языков, который игнорирует все недостатки парадигмы, но выпячивает их преимущества.

И это здесь, в ветке Delphi! Не в моих правилах такое терпеть.


Цитата:
Цитата:
Всё от ситуации зависит, когда я мониторил одну софтину там GC кушал сотые доли процента.

Если ты не понял, это совсем не означает, что GC всегда будет кушать сотые доли процента.

Конечно, не всегда. Если уж подсчет ссылок съедает до 5 процентов, то что говорить о GC? А ведь ты назвал эти пять процентов "адовым замедлением". Блин, это ли не двойные стандарты?

Напротив, все твои последние высказывания о managed коде были в неестественно светлых тонах. Случай, когда GC потребляет доли процента процессорного времени -- не правило, а исключение. Случай, когда JVM быстрее Delphi работает со строками, тоже нетипичен и не применим к случаю, когда скорость важна, и работа со строками действительно должна вестись максимально быстро.

А из твоих постов неокрепший ум мог сделать заключение, что managed код имеет лишь незначительные недостатки, обладая при этом огромными преимуществами.

Повторюсь, не здесь, не в ветке Delphi, не на моих глазах может это происходить без моей реакции.


Цитата:
Я ни разу не сказал, что GC не требователен к памяти. Речь была о скорости работы.

ты слишком много говорил о достоинствах, не упоминая недостатки. Получается однобоко.


Цитата:
Эти выводы сделаны тобой из некорректных тестов. В нормальных условиях GC безусловно быстрей.

тест был предложен тобой. Я лишь оформил и формализивал его, чтобы он был репрезентативен. Тест не на сферическом железе в вакууме, а на железе, адекватном задаче.

Твои же "нормальные условия" известны: почти двойное потребление памяти в managed коде, и значительная нагрузка на процессор в фоновом потоке. Однопоточная задача на минимум двухпоточном процессоре, чтобы обеспечить ресурсами сборщик мусора. Если бы ты был объективен, то сразу же упомянул это.

Цитата:
Опять вранье. Я говорил, что "GC более cache friendly", ты мне приписываешь "существенно оптимальнее".
В чем же разница между "cache friendly" и "существенно оптимальнее"?
Если нет существенного прироста по кэшу, то зачем писать это "cache friendly"? Зачем это маркетинговый буллшит?

Цитата:
С такими методами ведения дискуссий, проследуй-ка ты родной в пень
все, кто читает это, видят и мои, и твои методы ведения дискуссии. Им судить. Это и есть моя цель. Не выиграть в споре, а внести полную ясность, без умолчаний, для чтобы читающие эту дискуссию могли составить свое суждение.


Цитата:
И снова вранье. Я сказал, что порча буферов, да и не только буферов, это обычная ситуация для натива.
Это не так. Сложные, трудно диагностируемые ситуации, достаточно редки.
Другое дело, что новичка именно такие нечастые случаи могут довести до отчаянья, да и опытный программист поимеет нехилый геморрой с ними.

Да, в нашем лесу встречаются волки. Да, новичок не сможет писать на нативном языке сложные программы, без помощи сеньора, пока сам пару-тройку лет не походит по этому лесу.

Managed код дает дает более быстрый старт. В этой роще безопаснее, но она невелика, она огорожена, и лут в ней только тот, что одобрен ее хозяевами.
Дети, играйте в ней, но не смейте утверждать, что это и есть весь мир. Что в лес вообще не стоит выходить, потому что там волки и медведи с пустыми черными глазами. Подрастайте, и набирайтесь мужества.

Добавлено:
xpin2013

Цитата:
http://sourceforge.net/p/vdbi/home/Home/

хм, интересно.. Прежде не встречался.
Описание, на мой взгляд, довольно сумбурное, и непонятно, какова киллер-фича у этого проекта?
Вот я использую sqlite+mormot без DataSet обвязки. Думаю, это очень быстро, и при этом -- sqlite -- стандарт де-факто, а ориентация на SQL привносит возможможности масштабирования. А у вас что?
Я вижу, что в ваш проект вложены существенные усилия, но не понимаю, ради чего они..

Добавлено:
----
из-за тестов с явой я стал подозревать, что скорость работы любой, даже однопоточной Delphi программы, может быть увеличена за счет асинхронной работы с кучей.
Аллокацию без ожидания в отдельном потоке реализовать сложно, но вот освобождение памяти, можно сделать отложенным. Когда исполняемый поток лишь вносит объект в список на удаление, а специальный, выделенный поток , освобождает память из списка..
Это ускорит каждую функцию, в которой есть переменные управляемых типов, за счет экономии времени в эпилоге.
Это снизит затраты на блокировки в основных, пользовательских исполняемых нитях, когда блокировка происходит по причине освобождения ресурсов.
Да и насчет аллокации: почему бы не держать, с десяток, а то и сотню преаллоцированных буферов различных размеров под распространенные типы.

То есть в дополнение к уже существующему пулам small objects, добавить дежурный, либо даже ассоциированный с потоком пул, пополняемый по мере нужды, хотя тут я не уверен, что это ускорит программу.
Автор: Alexey_Gawrilow
Дата сообщения: 09.01.2015 23:49
Не, ну это же классика кун-фу:


Цитата:
Сначала ты не знаешь, что нельзя делать то-то
Потом знаешь, что нельзя делать то-то
Потом ты понимаешь, что иногда таки можно делать то-то
Ну а потом ты понимаешь, что помимо того-то существует еще шестьдесять шесть способов добиться желаемого, и все из них практически равноправны.
Когда тебя спрашивают "как мне добиться желаемого", ты быстро перебираешь в уме эти шестьдесять шесть способов, прикидываешь то общее, что в них есть, вздыхаешь и говоришь: "вообще-то, главное — гармония."
На вопрос обиженных учеников: "а как ее добиться?", ты говоришь: "никогда не делайте то-то".
Автор: kaz_av
Дата сообщения: 09.01.2015 23:50
AlekXL

Цитата:
Я смоделировал ситуацию ограниченных ресурсов, потому что ресурсы всегда ограничены.

Да не смеши ты меня. Память нынче стоит, как говно. У моего шестилетнего компа её 8Gb, а на полуторагодичном смарте 2Gb. Про серверы, где работают по настоящему нагруженные приложения и говорить нечего.


Цитата:
Я показал, что такой случай не показателен для действительно критического к производительности приложения.

Этот случай не показателен, фрагментация памяти не показательна... Это, как говорится, "Хоть ссы в глаза - всё божья роса".

В общем, я давно уже подвел итог:

Цитата:
Да вот хоть при сколь кратном, но если я жабе дам памяти и она сделает работу сильно быстрее, то дельфу хоть завали ресурсами, быстрее шевелиться она не сможет.

p.s. Бизнесу не интересны твои кульбиты с байтами, им нужно задачи решать. И у него есть деньги на память. За сим откланиваюсь. Приятных снов.
Автор: AlekXL
Дата сообщения: 10.01.2015 01:31

Цитата:
Память нынче стоит, как говно. У моего шестилетнего компа её 8Gb


Цитата:
Бизнесу не интересны твои кульбиты с байтами, им нужно задачи решать

бизнес как раз тщательно подсчитывает все расходы, как я понимаю. Кое-где они не важны. Кое-где очень даже. Ведь речь не только о памяти, но и о процессорном времени.
А процессоры не очень дешевы, особенно серверные. Особенно если этого железа сотни или тысячи, все стоят денег, все потребляют дорогое электричество, ну а программисты относительно недороги.
Alexey_Gawrilow

Цитата:
Не, ну это же классика кун-фу:

Глубокомысленные и абстрактные мудрости... глубокомысленны и абстрактны.
Я считаю, куда ценнее простые и конкретные идеи, способные стать откровением.
Автор: xpin2013
Дата сообщения: 10.01.2015 12:08
kaz_av

Цитата:
Лично наблюдал, как код на жабе делающий огромное количество операций со строками драл аналогичный дельфийский и плюсовый код.

Это ни о чём не говорит, мне например. Я наблюдал, как мой Delphi компонент TRefactor дерёт Delphi компонент TRegExspr который на встроенном ассемблере. У TRegExspr больше возможностей и больше вычислений, мне они были не нужны. В случае работы со строками нужно просто придерживаться одного единственного правила - самое тонкое место - это перераспределения памяти в случаях Add и S:=S+S;. Помогают Capacity, обратные циклы, отказ от TStrings, не копирование строки если можно запонить Offset и Length, потом соответственно пересчитать. То есть алгоритм на Delphi можно оптимизировать и на Delphi, без лишних перераспределений думаю будет драть и жабу.

AlekXL

Цитата:
хм, интересно.. Прежде не встречался. Описание, на мой взгляд, довольно сумбурное, и непонятно, какова киллер-фича у этого проекта? Вот я использую sqlite+mormot без DataSet обвязки. Думаю, это очень быстро, и при этом -- sqlite -- стандарт де-факто, а ориентация на SQL привносит возможможности масштабирования. А у вас что? Я вижу, что в ваш проект вложены существенные усилия, но не понимаю, ради чего они..

На счёт усилий - я их делал, когда было не лень. Это детище любви, а не пота и крови. Чаше всего я туда запихивал готовые, не меняющиеся куски из своих других проектов. Я бы не против хорошего описания, сам не силён - говорю же всё должно быть "полюбовно", то есть если не лень. Киллер-фича, не совсем понимаю, думаю их несколько. Попробую объяснить на пальцах:
1) Он нужен там где мне нужен клиентдатасет (это бывает не редко). Например у меня есть возможность забрать все данные из датасета присваиванием ссылки на внутренний массив потом отдать обратно. В этом режиме мы работаем так же как с датасетом, только нет ни единого вызова в модуль DB и далее. Мне надо было построить отчёт по менеджерам, когда SQL даёт мне три колонки - менеджер акция количество, надо было чтобы в шапке были имена менеджеров, то есть развернуть данные. В моём режиме при заполнении я могу динамически добавлять колонки, на эту задачу около 10 минут ушло, что бы я делал раньше не знаю.
2) Есть задачи, весьма специфичные, где мне это помогло. Например нужен был CD диск для тех кто не имеет хорошего интернета, чтобы дать полазить по огромному интернет порталу. Основное требование - чтобы не смогли тупым копированием слить огромную коллекцию картинок рисованных большим трудом в автокаде. Моя база шифрует в зависимости от пароля (в добавок её никто почти не знает, да и расширение другое). Чтобы пользователи не были в ступоре, пока я загружаю базу с CD - это 300 метров, я сделал прогресс бар загрузки. Плюсом я сделал хук файловой системы браузера, мои картинки браузер брал прямо из базы, минуя файловую систему (компонент для хука болтается в кодецентрал рядом с vdb).
3) У меня собственные индексы, которые я использовал в задаче Центрального Офиса, - это репликация нескольких баз. Базы могут бекапится и ресториться, по этому целостность/синхронность данных не гарантирована. Репликатору понадобилось восемь ступеней анализа данных. Мои индексы прикручиваются локально - в приложнии на любой Датасет, чем я и воспользовался. Так вот восемь ступеней анализа с локейтами многие ко многим, когда не требовалось изменять данные, занял всего 3 секунды (это вместе с запросами к базам, но этот замер был локальный, все базы крутились локально).
4) Это великолепное решение для больших объёмов - приложению требуется свыше 3х миллионов записей локально. Не часто бывает, но когда происходит, - память у меня есть, дома 8 гигов оператива, память есть, а решений нормальных нет. Дельфовый клиент датасет не выдерживает половины данных. IBX и FibPlus не виноваты - отдают то что им вернул протокол - OutOfMemory. Зачем мне сторонний клиентдатасет, если мой умеет записывать в один файл несколько таблиц-датасетов со всеми связками и индексами? В демке LocalIndex таблица городов с координатами 3.5 миллионов записей. Найдите свой город, задайте 20-30 км квадрат, и посмотрите соседние населённые пункты, фильтрация такая же быстрая как у сервака FireBird по айдишнику.
5) Всё находится в одном файлике - vdb.pas, это правило проекта. Вам доступно под отладчиком посмотреть всё, как работает конвертация, как работает поиск по индексу, как работают форейны, дефаулт значения и прочая лабуда. Вся подноготная баз данных в одном файле под отладчиком. Все данные находятся в одном массиве Variant-ов (BLOB поля это ускоренные одномерные массивы байтов), это тоже доступно отладчиком для просмотра.

Чёто я много уже написал, не знаю что важно, много ещё могу вспомнить, я туда выложил свой плагин adh для вставки дат, он является вырезкой из другого популярного на кодецентрал проекта я его лет 10 назад там выкладывал, потом убил. В adh я убрал абсолютно всё лишнее, оставил 3 файла. adh не имеет особого отношения к vdb, кроме того, что он и там используется, мне просто лень выкладывать на рапидшаре, когда мне не жалко - пусть пользуются.


Добавлено:
AlekXL

Цитата:
Случай, когда JVM быстрее Delphi работает со строками, тоже нетипичен и не применим к случаю, когда скорость важна, и работа со строками действительно должна вестись максимально быстро.


Цитата:
Ведь речь не только о памяти, но и о процессорном времени. А процессоры не очень дешевы, особенно серверные. Особенно если этого железа сотни или тысячи, все стоят денег, все потребляют дорогое электричество, ну а программисты относительно недороги.

Я всё в голову взять не могу на сколько серьёзно Вы лично воспринимаете этот спор. Открою одну тайну, у нас сервак раздаёт интернет и крутит веб службы на шарпе. Так как я знаком с шарпом, пробовал оптимизировать одну из них, работающую со строками. Она грузит 50% процессора сервера (то есть 2 ядра по 100%). Она не успевает отработать в тенении суток (24 часа), потом убивается без достигнутых результатов. Про автора, я слышал что он великолепный программист (конечно - знает шарп и как замылить мозг). Что он кодил я тупо оптимизировал, ну там было такое за что руки отрывать надо (например (важное - использовалось выражение LinQ - помоему так - отпадная фича шарпа) - Count(где есть Str+ ' ' в строке)+Count(где есть ' '+Str+ ' ' в строке)+Count(где есть ' '+Str в строке), то есть в сумму ' '+Str+ ' ' входят естественно части Str+ ' ' и ' '+Str. Что даёт эта цифра, думаю не скажет даже Бог программирования). Служба стала занимать 8 часов ночного времени, но там был запрос Постгрессу, который превышал 30 минут и транзакция рубилась серваком. Тогда я бросил эту службу - проще переписать на Delphi, думаю результаты её работы достижимы в сроки 10 минут с использованием моей локальной индексации.

Так что бросте спорить, уважаемый, с kaz_av. Думаю он мог бы написать и получше, но GC и весь перформенс вокруг интерпретируемых Фреймворков застилает глаза и работадателям, да и творцам кодерам на фремворках. Эти кодеры такое пишут, просто ужас. Я не имею ввиду тех кто пришёл туда, проведя долгие годы в нативе. Оппонента Вы не переспорите, а работодатели, пока только начинают осознавать ошибочность своих решений в сторону фремворков. Жаба нужна ВКонтакте, чтобы я в игрушки играл с друзьями.

Добавлено:






С Рождеством! И
С Наступающим Бинарным Новым Годом по программистскому стилю!

Напоминаю кто не в курсе.)))
тип TDataTime легко конвертируется в Double. По сути это один и тот же тип, поддерживающий ту же арифметику на уровне процессора. Так вот прикол - обратите внимание на четыре цифры перед точкой.
42014 - это 10.01.2015
42015 - это 11.01.2015
Очень редчайшее совпадение. Дату можно проверить следующим кодом:

Showmessage(DateToStr(42014.0))

Следующий точный Новый Год найден!!!!!!!!!!!!! (расстояние от нового года не более десяти дней)
Это Datetime(122358) то есть 01.01.2235 год! Следующий Новый Год будет ровно через 220-ть лет!

Отметьте программисты, такой случай очень редкий, как пролетающая комета, загадайте у феи ассемблера любое желание, всё сбудется!!!!!!!!!!!
Автор: yura371
Дата сообщения: 10.01.2015 13:57
Таблица 1 состоит из двух полей: Поле1 и Поле2. Поле1 - пустое, Поле2-заполнено. Вопрос:
Почему после выполнения SQL-запроса "insert into "Таблица1" (Поле1) values ('Значение1')",
"Значение 1" добавляется в поле "Поле1" после последней записи в другом поле в этой же таблице, а не сразу же в первую строку поля?

Суть в картинке:
http://s020.radikal.ru/i702/1501/c2/4f85195a374f.png
Автор: ChSerg
Дата сообщения: 10.01.2015 14:15
yura371
Сортировку поставьте нужную у таблицы. Либо через order by, либо в гридине.
Автор: regkz
Дата сообщения: 10.01.2015 15:01
yura371
для обновления, я так понял, именно это нужно, используется оператор Update
Автор: landy
Дата сообщения: 10.01.2015 16:57

Цитата:
insert into "Таблица1" (Поле1) values ('Значение1')

Если ты хочешь добавить значение к уже существующей строке, нужно писать

update "Таблица1" set Поле1 = Поле1 + 'Значение1';

Если же ты хочешь универсальный оператор (делающий и вставку и обновление) - почитай про MERGE
Автор: yura371
Дата сообщения: 10.01.2015 19:43
landy, почему то Ваш код заполняет все записи поля значением 'Значение1', а не одну строку?
Автор: ZloyBrawler
Дата сообщения: 10.01.2015 20:09

Цитата:
landy, почему то Ваш код заполняет все записи поля значением 'Значение1', а не одну строку?

Ну может потому, что еще нужно добавить условие какие строки менять.
WHERE <условие>

курите http://msdn.microsoft.com/ru-ru/library/ms177523.aspx

UPDATE Person.vStateProvinceCountryRegion
SET CountryRegionName = 'United States of America'
WHERE CountryRegionName = 'United States';
Автор: yura371
Дата сообщения: 10.01.2015 20:16
А как правильно записать данные в базу данных через SQLDataSet?
Я написал такой код:
Form3.SQLDataSet1.First;
Form3.SQLDataSet1.FieldByName('Поле1').AsString:='Значение1';

Но нет никаких результатов его выполнения. Также я добавлял вначале Form3.SQLDataSet1.Edit выходит ошибка: "SQLDataSet1: Can not modify a read-only dataset." Я также читал про связку DataSetProvider1 -> ClientDataSet1, но я не понимаю как это реализовать и настроить.
Автор: AlekXL
Дата сообщения: 10.01.2015 20:23
xpin2013

Цитата:
Я всё в голову взять не могу на сколько серьёзно Вы лично воспринимаете этот спор

Серьезно. Опытные и без меня все понимают, но я не хочу, чтобы даже здесь, нам некие типусы ездили по ушам новичков насчет чудес managed кода.
А дискуссия, считай, уже закончена. Считаю, по очкам я выиграл.
----
Друзья, я ищу контейнер -- неблокирующую FIFO очередь, в которой есть
TryPush(v):boolean
TryPop(out val):boolean
без ожидания.

В гугле нашлось flqueue но в ней нет защиты от переполнения, как и TryPush, TryPop

Еще нашлось wqueue, но там тоже нет TryPush, TryPop, а код ужасный.

Также в OtlContainers есть TOmniBaseQueue, в которой есть все, но она работает с OmniValue, а реализация выглядит мудрено.

Может, кто подскажет реализацию получше?

Автор: regkz
Дата сообщения: 10.01.2015 20:42
yura371
а может немного голову напрячь и решить самому свою лабу?
Автор: AlekXL
Дата сообщения: 10.01.2015 21:26
regkz

Цитата:
а может немного голову напрячь и решить самому свою лабу?

а может, все таки помогать?
yura371

в справке прочти
There is no built-in editing support: you can only edit the data in an SQL dataset by explicitly creating an SQL UPDATE command or by connecting the dataset to a client dataset using a provider

Автор: landy
Дата сообщения: 10.01.2015 21:38

Цитата:
Form3.SQLDataSet1.FieldByName('Поле1').AsString:='Значение1';

Проще будет использовать объект TXXTable, чтобы была возможность сохранять изменения в базе.
Автор: xpin2013
Дата сообщения: 11.01.2015 00:57
AlekXL
Кстати сейчас встретился с ошибкой финализации в XE7. Я портировал туда старые компоненты, которые перестали выпускать после Delphi7. Когда на end; в отладке нажать F7, то начинаем гулять по ассемблерному коду финализации. Программа валилась на _LStrClr. В процедуре, в локальных переменных была только TBookmarkStr. Я ей присвоил пустую строку перед выходом, ошибка исчезла. Ну в общем, исправил в чужом коде за 10 минут, и КвелитиЦентрал мне не понадобился. Но предупреждаю, какие то косяки ещё есть и в XE7.
Автор: AlekXL
Дата сообщения: 11.01.2015 10:12
xpin2013


Цитата:
Кстати сейчас встретился с ошибкой финализации в XE7.

если там действительно баг, нужно обязательно его отправить в qc
они исправляют.
так что либо сами запостите, либо поточнее опишите его здесь, с примером, я оформлю.
Автор: xpin2013
Дата сообщения: 11.01.2015 10:54

Цитата:
если там действительно баг, нужно обязательно его отправить в qc они исправляют. так что либо сами запостите, либо поточнее опишите его здесь, с примером, я оформлю.

Тут некоторые нюансы есть, сейчас думаю как это сделать проще...

Добавлено:
AlekXL

Цитата:
если там действительно баг, нужно обязательно его отправить в qc они исправляют. так что либо сами запостите, либо поточнее опишите его здесь, с примером, я оформлю.

Написал пример ошибки. Отпишите в QC пожалуйста, Вы обещали, можете упомянуть меня (там и в QC - xpin). В примере нужна заполненная таблица. Я взял FireDac с FireBird, но база не важна. Валится на Button1Click.
[more=Unit1.pas]
Код: [no]unit Unit1;

interface

uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Data.DB,
Vcl.Grids, Vcl.DBGrids, Vcl.StdCtrls, FireDAC.Stan.Intf, FireDAC.Stan.Option,
FireDAC.Stan.Error, FireDAC.UI.Intf, FireDAC.Phys.Intf, FireDAC.Stan.Def,
FireDAC.Stan.Pool, FireDAC.Stan.Async, FireDAC.Phys, FireDAC.Phys.FB,
FireDAC.Phys.FBDef, FireDAC.Stan.Param, FireDAC.DatS, FireDAC.DApt.Intf,
FireDAC.DApt, FireDAC.VCLUI.Wait, FireDAC.Comp.UI, FireDAC.Comp.DataSet,
FireDAC.Comp.Client;

type
TForm1 = class(TForm)
DBGrid1: TDBGrid;
DataSource1: TDataSource;
Button1: TButton;
FDConnection1: TFDConnection;
FDTransaction1: TFDTransaction;
FDTable1: TFDTable;
FDGUIxWaitCursor1: TFDGUIxWaitCursor;
FDTable1ID_VARIABLE: TIntegerField;
FDTable1ID_COMPLECT: TIntegerField;
FDTable1NAME_VARIABLE: TStringField;
FDTable1VALUE_VARIABLE: TStringField;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
Current : TBookMarkStr;
V : Variant;
begin
Current := TBookmarkStr(FDTable1.Bookmark);
V := Null;
FDTable1.Bookmark := TBookmark(Current);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
FDConnection1.Open;
FDTable1.Open;
end;

end.[/no]
Автор: kaz_av
Дата сообщения: 11.01.2015 14:15
xpin2013

Цитата:
Ну в общем, исправил в чужом коде за 10 минут, и КвелитиЦентрал мне не понадобился. Но предупреждаю, какие то косяки ещё есть и в XE7.

У тебя не ошибка финализации, а некорректное приведение типа, которое портит память.
Автор: xpin2013
Дата сообщения: 11.01.2015 15:31
kaz_av

Цитата:
У тебя не ошибка финализации, а некорректное приведение типа, которое портит память.

1) Если бы портилась память то

Код: [no]var
Current : TBookMarkStr;
V : Variant;
begin
Current := TBookmarkStr(FDTable1.Bookmark);
V := Null;
FDTable1.Bookmark := TBookmark(Current);
Current := ''; //<-- Вот это бы не помогло.
end;
...
initialization
ReportMemoryLeaksOnShutdown := true;
end.[/no]
Автор: NickNNN
Дата сообщения: 11.01.2015 15:46

Цитата:
1) Если бы портилась память то


Если писать всякий бред, то не только в финализации можно проблем нахвататься.

По поводу примера - там две строчки кода, там больше нечему валится кроме как в финализации.

kaz_av четко указал причину, не вертите - пишите на QC, там доступно и вежливо напишут кто идиот
Автор: xpin2013
Дата сообщения: 11.01.2015 15:54
NickNNN

Цитата:
По поводу примера - там две строчки кода, там больше нечему валится кроме как в финализации.

Ошибаетесь. И Вы прочитайте пункт 1. Current := '' это то, что делает (должна делать) финализация. Ошибка должна была валиться в этой строке - освобождается память, ошибки - её нет.
2.
Цитата:
initialization ReportMemoryLeaksOnShutdown := true;
не выдаёт потерянной памяти, и нет двойного высвобождения памяти, значит Current := '' вполне корректен.
3)
Цитата:
Если писать всякий бред
, вот и не пишите.

Автор: Vadimsta
Дата сообщения: 11.01.2015 16:15
xpin2013
Ах-ах, ностальгия, 2011 год, стандартные проблемы обновления работы с источниками данных... Решённые и разобранные по косточкам в том же году.

Из справочной системы Delphi XE7:

Note: Any use of either TBookmarkStr or Pointer in user code should change to TBookmark. The TBookmarkStr type is deprecated.

Поэтому на QC даже обсуждать это не будут (начиная с Delphi 2009). Я даже не буду приводить ассемблерные листинги.

Отмечу, что в стабильной ветке Free Pascal всё наоборот - используется именно TBookmarkStr: http://www.freepascal.org/docs-html/fcl/db/tbookmark.html .

P.S. Если очень хочется поизвращаться со строками, можно достаточно безопасно использовать StringOf(Букмарк) и BytesOf(Строка).

P.P.S. Из то же справки:
Note: Different types of datasets can implement bookmarks differently. Do not use a TBookmark from one type of dataset (for example, a client dataset) with methods on another type of dataset (for example, an InterBase Express dataset).
Автор: NickNNN
Дата сообщения: 11.01.2015 16:21
Vadimsta, кто же читает рекомендации при обновлении от одной версии к другой. Это ж для умников, а depricated вообще для тру'сов
Автор: Vadimsta
Дата сообщения: 11.01.2015 16:37
Ведь даже на сайте прекрасно написано в What's New in Delphi and C++Builder 2009 (http://docwiki.embarcadero.com/RADStudio/XE7/en/What%27s_New_in_Delphi_and_C%2B%2BBuilder_2009)

TDataSet Changes in Bookmark Handling: DB.TDataSet has some significant changes in its handling of Bookmarks:
- The TBookmarkStr type is being deprecated.
- The TBookmark type definition has changed from Pointer to TBytes, which means that it is now reference-counted and lifetime-managed.
- TDataSet.Bookmark property now returns a TBookmark instead of a TBookmarkStr.
- Any use of either TBookmarkStr or Pointer in user code should change to TBookmark.
- The following code results in invalid access to freed memory on the GotoBookmark line, because no valid TBookmark reference is made:

Код: [no]var
Bookmark: Pointer;
begin
Bookmark := MyDataSet.GetBookmark;
...
MyDataSet.GotoBookmark(Bookmark);[/no]
Автор: xpin2013
Дата сообщения: 11.01.2015 17:00
Vadimsta

Цитата:
Из справочной системы Delphi XE7: Note: Any use of either TBookmarkStr or Pointer in user code should change to TBookmark. The TBookmarkStr type is deprecated.

1) Из моей справочной системы в Delphi 2010 этот код прекрасно работает (XE3 может и раньше не работает так как генерик).
2) Ошибки должны быть вразумительными, не все такие прошаренные как я.
3) При чём сдесь TBookmarkStr вообще????? Вы хоть проверьте этот текст.
type TWordArray = TArray<Word>;
var
S: AnsiString;
W: TWordArray;
begin
S := AnsiString(W);
Это преобразование компилируется на ура и влечёт те же ошибки...

Кому интересно поразбирать косточки.

Код: [no]var
MonitorC: PPointer;
MonitorI: PInteger;

function xxx: AnsiString;
begin result := #0#1#2#3; end;

procedure TForm1.Button1Click(Sender: TObject);
var
Current : TBookMarkStr;
V : Variant;
begin
Current := TBookmarkStr(FDTable1.Bookmark);
//Current := TBookmarkStr(xxx);
//V := Null;
//FDTable1.Bookmark := TBookmark(Current);
MonitorC := @Current;
MonitorI := Pointer(Current);
Dec(MonitorI, 2);
// Current := '';
end;[/no]
Автор: NickNNN
Дата сообщения: 11.01.2015 18:29

Цитата:
Хватит умничать. Я не на пустом месте этот пример взял. Возьмите тот же ExpressQuantumGrid 3.2.2 (DevExpress Delphi7) и портируйте его в Delphi XE7


А обновления сторонних компонентов для кого выходят? И что производители зря пишут что добавилась поддержка новых версий Delphi ? Или вы думаете там идиоты сидят, вместо того чтобы "портировать" просто код переделывают от нечего делают?

Свой проект переводил сразу с D6 на XE3, потом с XE3 на XE7. Сторонние компоненты обновил. Странно, все работает хорошо. Наверно нужно было FastReport и DevExpress портировать, не читать рекомендации, наделать кучу ошибок и потом кричать на весь мир о глючности последней среды

Продолжать дискуссию считаю бессмысленной, уже несколько человек указывают Вам на грубые ошибки, а вы все заладили "компилятор же пропустил, значит должен работать"

Кстати, никто никого не заставляет обновлять среду разработки, не нравится - не работайте. В варесе среда появляется с минимальной задержкой от официальной, можно вполне оценить качество продукта
Автор: xpin2013
Дата сообщения: 11.01.2015 18:41
NickNNN

Цитата:
Или вы думаете там идиоты сидят, вместо того чтобы "портировать" просто код переделывают от нечего делают?

Если утверждаете, то не плохо бы сначало узнать что Вы утверждаете. Попридержите язык, хватит хамить здесь. Через слово у Вас идиоты.


Цитата:
Продолжать дискуссию считаю бессмысленной


Цитата:
уже несколько человек указывают Вам на грубые ошибки,

ога. Они ещё скажут что преобразование Integer(Pointer(String(S))):=0 грубая ошибка, хотя этим трюком пользовался стринглист и описывалось в каждом учебнике как уловка. Ну надо же грубая ошибка которую я исправил с помощью Current:=''. Это же нарушение, это хаккерство какое-то.

Добавлено:

Цитата:
и потом кричать на весь мир о глючности последней среды

Держу мышку над надписью Сообщить модератору.
Автор: landy
Дата сообщения: 11.01.2015 18:58

Цитата:
ExpressQuantumGrid 3.2.2 прекратил существование после Delphi7. Нет никого кроме добровольцев типа меня. Могу дать ссылку на портированный 3.2.2 под XE3 там зип с паролём как наш сайт, видимо "идиоты" какие-то выкладывали

Кстати, xpin2013, я бы попросил опубликовать эту ссылку - у меня есть один недопортированный проект, который как раз застрял на ExpressQuantumGrid 3.

Страницы: 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129

Предыдущая тема: Отмена встречи в Outlook из Excel VBA


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.