Bugs / Найденные баги (1)

Russian main discussion
Locked
  • Author
  • Message
Offline
Posts: 582
Joined: Mon Apr 08, 2013 9:50 pm
Location: Win7SP1x64, APx64

Post by Drugmix »

Instructor
мне, кстати, тоже не нравится это. Может можно переделать так, чтобы акелпад не начинал закрывать вкладки, пока не удостоверился, что ни одна из них не требует решения пользователя?
т.е. сначала получать решение пользователя по каждой из нуждающихся в таком решении и только потом закрывать вкладки, а если пользователь на одном из решений жмёт "отмена", то закрытие бы вкладок останавливалось.


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

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

Offline
Posts: 7
Joined: Fri Apr 04, 2014 10:00 am
Location: narodmon.ru
Contact:

Post by narodmon »

День добрый, коллеги.
Сходу несколько багов с критической нехваткой памяти.

Исходная: имеем комп с 4гигами ОЗУ + файл подкачки и жалкий текстовый файл на 100мег.

В процессе правки по 1-2 символа, но многократно (десятки раз) получаем критическую ошибку нехватки памяти....как так?

Такое впечатление, что при правке всего 1 символа в памяти кешируется весь файл целиком, коли после десятка итераций перестает хватать 4 гигов. Неужто нельзя для отката изменений запоминать только позицию и измененный фрагмент?

Далее... Почему при исчерпании памяти нельзя пожертвовать самыми старыми логами изменений дабы высвободить память?
Т.е. к примеру при 10й правке удалять из памяти историю при 1й.

Особенно актуальна данная проблема при использовании PCRE:
Крайне раздражает, что при длительных автозаменах интерфейс приложения зависает наглухо и даже по Esc его нельзя прервать, что было бы крайне полезно успеть сохранить на диск хотя бы уже обработанный фрагмент данных, а не начинать с 0 снова и снова и снова.

При автозамене выводите пож-та индикатор прогресса, (кол-во обработанных строк и % от общего числа), чтобы хоть как то было заметно что приложение не "повисло" и сколько еще осталось ждать прикинуть можно было.

PS В остальном крайне полезное приложение, спасибо!

PPS Сам являюсь разработчиком 15+ лет, посему рекомендаций в духе "а вы пробовали выключить и снова включить?" не давать)

DV
Offline
Posts: 1250
Joined: Thu Nov 16, 2006 11:53 am
Location: Kyiv, Ukraine

Post by DV »

narodmon
С помощью элементарного наблюдения в Task Manager за процессом AkelPad можно легко увидеть, что при операциях Replace All выделяется (кушается) дополнительная память, соответствующая размеру файла.
Судя по всему, это и есть описанная вами ситуация. Потому что при печати/вставке новых символов/слов/предложений или удалении старых никакого особого перевыделения памяти я не заметил.
Ваше предложение запоминать в Undo только изменённые куски имеет смысл, но сейчас так не сделано из соображений быстродействия. Аргументация: сделав, скажем, 10000 замен в Replace All, соответствующая операция Undo по частям вызвалась бы 10000 раз для каждого модифицированного куска. Что было бы весьма небыстро, учитывая то, что каждая замена в общем случае ведёт к сдвигам в текстовом буфере, что приводит к необходимости перекопирования текста и к перевыделению памяти. Сейчас же весь текст до операции Replace All помещается в буфер Undo - и при необходимости восстанавливается одной операцией Undo.
А вот идея стирать старые части буфера Undo при прогнозируемой нехватке памяти - это да, хорошее предложение.

Offline
Posts: 582
Joined: Mon Apr 08, 2013 9:50 pm
Location: Win7SP1x64, APx64

Post by Drugmix »

DV wrote:narodmon
Ваше предложение запоминать в Undo только изменённые куски имеет смысл, но сейчас так не сделано из соображений быстродействия. Аргументация: сделав, скажем, 10000 замен в Replace All, соответствующая операция Undo по частям вызвалась бы 10000 раз для каждого модифицированного куска.
Так произойдёт в любом случае. У кнопки "undo" ведь нет подменю, где можно было бы выбрать кол-во шагов отмены.
Если требуется откатиться на 10000 шагов назад, то в любом случае придётся пройти 10000 шагов отмены [о существовании скриптов реализующих функционал "сделать n шагов undo" - мне не известно].

Разница в текущем и предлагаемом подходах в том, что при сохранении undo шагов в виде diff'ов (а не копий всего текста (snapshot'ов) как сейчас) при создании undo истории и при выполнении undo действий - акелпаду придётся не просто прочитать из памяти нужный snapshot, а выполнить обработку всего файла ещё раз, что, как я понимаю, в ряде случаев будет заметно быстрее, а в другом ряде случаев - значительно медленнее.
DV wrote:Что было бы весьма небыстро, учитывая то, что каждая замена в общем случае ведёт к сдвигам в текстовом буфере, что приводит к необходимости перекопирования текста и к перевыделению памяти. Сейчас же весь текст до операции Replace All помещается в буфер Undo - и при необходимости восстанавливается одной операцией Undo.
Я понял жалобу narodmon несколько иначе: насколько я понял, он предлагает сохранять undo шаги diff'ами, а не snapshot'ами, как это сейчас. Его жалоба ведь была на нехватку памяти после 10-ого replaceAll, т.е. когда памяти перестало хватать на 10-ый snapshot.

Offline
Posts: 1862
Joined: Mon Aug 06, 2007 1:07 pm
Contact:

Post by Infocatcher »

Drugmix wrote:[о существовании скриптов реализующих функционал "сделать n шагов undo" - мне не известно].
Это как раз не проблема: undoRedoAll.js.

DV
Offline
Posts: 1250
Joined: Thu Nov 16, 2006 11:53 am
Location: Kyiv, Ukraine

Post by DV »

Drugmix,
Я объяснял, как сделано сейчас для Replace All - и почему сделано именно так. В частности, я объяснял, что Undo для Replace All выполнить гораздо быстрее для одного большого куска (как это и сделано сейчас), чем для множества мелких diff-ов.
Чтобы стало понятнее, я приведу ниже некоторый псевдо-код:

Code: Select all

string s = "... 1 million characters string ...";

{
  // Replace All 1 - current implementation
  string old_s = s;
  size_t replaceCount = s.replaceAll(findWhat, replaceWith);
  // Undo 1 - current implementation
  s = old_s;
}

{
  // Replace All 2 - proposed implementation
  vector<UndoDiff> arrayOfUndo = s.replaceAll(findWhat, replaceWith);
  // Undo 2 - proposed implementation
  for (size_t i = 0; i < arrayOfUndo.size(); ++i)
  {
    s.replace(arrayOfUndo[i]);
  }
}
Ну и как по-вашему, что быстрее: выполнить один раз "s = old_s;" или гонять цикл "s.replace(arrayOfUndo);", в котором на каждом шаге содержимое строки "s" переписывается?

DV
Offline
Posts: 1250
Joined: Thu Nov 16, 2006 11:53 am
Location: Kyiv, Ukraine

Post by DV »

DV wrote:Ну и как по-вашему, что быстрее: выполнить один раз "s = old_s;" или гонять цикл "s.replace(arrayOfUndo);", в котором на каждом шаге содержимое строки "s" переписывается?

Хотя, если подумать, можно было бы оптимизировать примерно так:

Code: Select all

// New implementation of Undo
s = constructString(s, arrayOfUndo);
где функция constructString выглядела бы как-то так:

Code: Select all

string constructString(const string& s, const vector<UndoDiff>& arrayOfUndo)
{
  size_t pos = 0;
  string ret = "";
  ret.reserve(s.length()); // pre-reserve some buffer
  vector<UndoDiff>::const_iterator itrUndo = arrayOfUndo.begin();
  for ( ; itrUndo != arrayOfUndo.end(); ++itrUndo)
  {
    ret += s.substr(pos, itrUndo->pos); // copy the string part before the Undo's position
    ret += itrUndo->findWhat; // restore the replaced substring
    pos += itrUndo->pos + itrUndo->len; // position after the Undo's substring
  }
  ret += s.substr(arrayOfUndo.last().pos + arrayOfUndo.last().len); // remaining part of the string after the last Undo position
  return ret;
}
Таким образом, мы бы восстанавливали исходную строку, конструируя её по частям, таким образом не вызывая s.replace() в цикле. Такой новый подход сочетал бы в себе предложенный Undo по частям и был бы почти таким же быстрым, как с единственной операцией "s = s_old;".

Offline
Posts: 582
Joined: Mon Apr 08, 2013 9:50 pm
Location: Win7SP1x64, APx64

Post by Drugmix »

DV wrote:Drugmix,
Я объяснял, как сделано сейчас для Replace All - и почему сделано именно так. В частности, я объяснял, что Undo для Replace All выполнить гораздо быстрее для одного большого куска (как это и сделано сейчас), чем для множества мелких diff-ов.
Я это прекрасно понимал, когда писал свой комментарий, в котором я указал на то, что у каждого из подходов (текущего и предлагаемого) - есть свои плюсы и свои минусы.
Проиллюстрирую это заявление псевдо-графической таблицею:

Code: Select all

┌───────────────────────┬──────────────────┬─────────────────────────────┐
│                       │потребление памяти│скорость выполнения undo/redo│
├───────────────────────┼──────────────────┼─────────────────────────────┤
│текущая реализация     │         -        │              +              │
├───────────────────────┼──────────────────┼─────────────────────────────┤
│предложенная реализация│         +        │              -              │
└───────────────────────┴──────────────────┴─────────────────────────────┘

Offline
Posts: 7
Joined: Fri Apr 04, 2014 10:00 am
Location: narodmon.ru
Contact:

Post by narodmon »

Drugmix wrote:Я понял жалобу narodmon несколько иначе: насколько я понял, он предлагает сохранять undo шаги diff'ами, а не snapshot'ами, как это сейчас. Его жалоба ведь была на нехватку памяти после 10-ого replaceAll, т.е. когда памяти перестало хватать на 10-ый snapshot.
Вот! Именно это и имелось ввиду, жаль, что не все читают внимательно суть описываемой проблемы!
Соотношение 2*4096 >> 100 несколько напрягает своей архаичностью и самой возможностью критической ошибки нехватки памяти при таких раскладах.

Также комментаторы пропустили из виду 2ю часть пожелания, про удаление устаревших снапшотов дабы предотвратить ошибку с памятью.

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

Кстати навскидку насколько вообще популярны команды undo/redo по-вашему? за себя могу сказать, что отключил бы их нафиг ради отсутствия проблем с памятью и производительности ибо лишь каждый 100-1000й раз бывает что то надо откатить, но ито проще файл переоткрыть не сохраняя на диск.

2DV А без скриптов слабо устранить проблему нерационального, мягко говоря, использования памяти ?)
Если б речь шла о программинге, а не про GUI, то уж точно не на этом форуме писал бы о баге. Жестких однотипных алгоритмов автозамены нет, поэтому без шаманства и бубнов давайте.

Offline
Posts: 582
Joined: Mon Apr 08, 2013 9:50 pm
Location: Win7SP1x64, APx64

Post by Drugmix »

narodmon wrote:Также комментаторы пропустили из виду 2ю часть пожелания, про удаление устаревших снапшотов дабы предотвратить ошибку с памятью.
Не правда:
DV wrote:А вот идея стирать старые части буфера Undo при прогнозируемой нехватке памяти - это да, хорошее предложение.
narodmon wrote:Сравнение по скорости какой то маркетинговый ход не иначе... ибо она и при текущей реализации далека от идеала. Грубо говоря она больше зависит от качества реализации, чем от выбранного метода ибо у обоих есть + и -, но при одном из них еще и критические ошибки возникают.... только мне кажется что выбор очевиден?
Наличие критической ошибки - это отдельный факт, никак не связанный с текущей и предложенной моделями работы undo/redo.
narodmon wrote:Кстати навскидку насколько вообще популярны команды undo/redo по-вашему? за себя могу сказать, что отключил бы их нафиг ради отсутствия проблем с памятью и производительности ибо лишь каждый 100-1000й раз бывает что то надо откатить, но ито проще файл переоткрыть не сохраняя на диск.
Отвечаю за себя: для меня это критическая функция и использую я её ОЧЕНЬ часто. Я испытываю почти физическую боль, когда обстоятельства вынуждают пользоваться виндовым notepad.exe в котором запоминается только 1 шаг undo/redo. Без этой функции, я бы перешёл обратно на Notepad++.
narodmon wrote:А без скриптов слабо устранить проблему нерационального, мягко говоря, использования памяти ?)
А вам? Код акелпада - открыт, критическая ошибка о нехватки памяти - явный баг. Я уверен, что если вы предложите патч исправляющий этот баг Instructor'у - он его с удовольствием включит в релиз.

Offline
Posts: 7
Joined: Fri Apr 04, 2014 10:00 am
Location: narodmon.ru
Contact:

Post by narodmon »

Drugmix wrote:А вам? Код акелпада - открыт, критическая ошибка о нехватки памяти - явный баг. Я уверен, что если вы предложите патч исправляющий этот баг Instructor'у - он его с удовольствием включит в релиз.
Мне - в данном случае слабо да, ибо если всегда изобретать велосипед самому то и жизни не хватит. Эх вот если б за меня кто мои баги исправлял даже в открытых проектах... ммм... прям мечта разработчика ибо своевременные багфиксы самое ответственное в разработке. Да и почему мое время менее ценно, чем Instructor'а ? я же прошу исправить очевидный баг, наносящий вред репутации приложения, но никаких сроков не ставлю, т.е. по сути выполнил роль стороннего халявного тестировщика с подробным описанием ситуации, а не багрепорта в духе "не работает потому что не работает".
PS Про виндновое убожество и речи быть не может, в хитпарад его вообще стыдно включать.

Offline
Posts: 582
Joined: Mon Apr 08, 2013 9:50 pm
Location: Win7SP1x64, APx64

Post by Drugmix »

narodmon wrote:Мне - в данном случае слабо да, ибо если всегда изобретать велосипед самому то и жизни не хватит.
Про велосипед тут не в тему. Есть баг - надо править.
narodmon wrote:Эх вот если б за меня кто мои баги исправлял даже в открытых проектах... ммм... прям мечта разработчика ибо своевременные багфиксы самое ответственное в разработке.
Если б ваши проекты были бы сильно популярны, то нашлись бы и люди, которые добровольно предлагали бы патчи. Отличный пример - проект Линуса Торвальдса.
narodmon wrote:Да и почему мое время менее ценно, чем Instructor'а?
Странный вопрос. Разве кто-то утверждал такое? Если да, то вы поставьте его в тупик аналогичным вопросом о том, чем время Instructor'а менее ценно, чем ваше.
narodmon wrote:я же прошу исправить очевидный баг, наносящий вред репутации приложения, но никаких сроков не ставлю, т.е. по сути выполнил роль стороннего халявного тестировщика с подробным описанием ситуации, а не багрепорта в духе "не работает потому что не работает".
Instructor - интроверт :). Он частенько багрепорты молча принимает к сведению, не давая никакой обратной связи. Но в случае отказа - иногда и даёт их обоснования.

Offline
Site Admin
Posts: 6311
Joined: Thu Jul 06, 2006 7:20 am

Post by Instructor »

Drugmix wrote:Есть баг - надо править.
Баг - это, когда что-то работает не так, как задумано. Тут все работает штатно. В данном случае, как уже отмечал DV, первым делом нужно сделать банальное действие - открыть "Диспетчер задач" и последить. Замена всего текста выделяет буфер в размер всего файла. Мало того, при самой операции и до ее окончания может использоваться удвоенный буфер памяти, при определенных параметрах замены.

Если файл большой и планируются замены по всему файлу, то имеет смысл временно отключить запоминание "Отмен":
Главное меню -> Настройки -> Параметры... -> Редактор 1 -> Лимит отмен = 0

Offline
Posts: 582
Joined: Mon Apr 08, 2013 9:50 pm
Location: Win7SP1x64, APx64

Post by Drugmix »

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

Offline
Site Admin
Posts: 6311
Joined: Thu Jul 06, 2006 7:20 am

Post by Instructor »

Немного грубо, но "слышал звон, да не знает, где он". Будьте аккуратнее в оценках не владея предметом.

Выдается следующее сообщение: "Критическая ошибка: недостаточно памяти. Рекомендуется завершить работу программы."
Locked