Спасибо большое за этот пост!
Вы отлично написали, просто не в бровь, а в глаз.
Только сложно убедить того, кто не пользовался этим.
Об этом писал Грэм в Beating the Averages про гипотетического программиста на Blub.
По поводу выделения гигабайта или 100 Мб — как поступают в реализации std::vector? Или там всегда известно какой длины массив туда собираются сохранить?
То же и про кольцевой буфер.
Конкретные реализации дают выигрыш в конкретных случаях.
Про бесплатный сыр никто не говорил и не ожидал.
Менторский тон заключительной фразы не способствует приятному обсуждению.
Почему неидеоматично?
Классикой написания на хаскелле считается выведение всех операций ввода-вывода в отдельные функции и тем самым получение в остальной программе чисто функционального стиля.
Чем же хуже вариант с выведением в отдельные функции операций, оптимизирующих работу с памятью и другими ресурсами?
Да зачем мне вас троллить?
Просто не знаю как уже донести эту мысль (которая здесь и другими участниками высказывалась), что для производительности можно выделять память из пула.
Уж не напоминаю, что в самой статье тема производительности тоже затрагивалась, причём с однозначным ответом на этот вопрос.
Внутри MemoryManager.GetMat может быть, например, кольцевой буфер.
Или дерево с ссылками на свободные chunkи памяти.
Или что угодно, что может оперировать с _предвыделенными_ областями памяти.
Единственная задача — предоставить абстракцию, чтобы в этот логический блок памяти записывались данные только для матрицы dst, и не записывались никакие другие.
Принципиальная реализация не важна.
Вы лучше скажите почему «выделение» — это всегда выделение.
Может я что-то неправильно понимаю в ваших словах.
«Выделение» памяти может быть без выделения.
Ну вот, например, как здесь C++: Custom memory allocation
(И это я ещё не вспоминаю о том, что автор статьи явно указал, что пишет не о проблемах производительности :))
Буферы так же будут освобождаться, когда отработают.
Можно вручную, а можно предусмотреть и автоматическую сборку мусора (которая, можно сказать, из FP родом).
Просто вы говорите, что выделение памяти на каждый вызов функции затормаживает обработку, поэтому надо выделять заранее буфер и всё время его передавать в функцию, чтобы сэкономить на операции выделения памяти.
А я говорю, что скорость выделения может быть очень высока и этим можно пренебречь.
Тут у вас конфликт в двух посылках (почти как у Печкина в Простоквашино :)):
1. Выделение памяти ведёт к снижению производительности
2. Написать в функциональном стиле без выделения памяти невозможно
Отсюда вывод: написать в функциональном стиле без снижения производительности невозможно.
Но здесь «выделение памяти» в этих двух пунктах может иметь разное значение.
Даже в самом кошерном ОО С++ если нужна сверхскорость при работе с объектами, начинают переопределять new() с использованием нестандартных аллокаторов.
Кто мешает написать функцию ФП с «выделением» памяти, которое на самом деле будет просто возвращать ссылку на область памяти из предвыделенного пула?
1. Это откуда вы взяли, что стабилен? Даже по вашей ссылке из п.2 цитата
В теории реляционных баз данных таблица представляет собой изначально неупорядоченный набор записей. Единственный способ идентифицировать определённую запись в этой таблице — это указать набор значений одного или нескольких полей, который был бы уникальным для этой записи.
2. А вы задумывались, что я не говорил, что суррогатные ключи — это зло?
3. Что мешает назвать первую коробку второй, а вторую первой?
4. Какое это имеет отношение к картофелинам?
1. В теории реляционных БД нет операторов limit и offset, кортеж может идентифицироваться только по значениям атрибутов.
2. Так в чём плюс неизменности номера пенсионного? Особенно если учесть, что он никак не привязан к объекту, кроме произвольной договорённости.
3. Вам ничто не мешает в таком случае завести два и более объектов, соответствующих одному объекту реального мира. Опять же в реляционных БД для отношения (моделирующего объекты реального мира) с искуственным первичным ключом обязательно должен быть определён альтернативный уникальный ключ. Иначе неминуемо нарушение целостности и коллизии.
1. В теории реляционных БД порядок записей не определён до выполнения оператора order by.
2. Это я даже не понял.
3. О чём и речь — и именно поэтому порядковый номер, если он не является свойством коробки, как объекта реального мира, не может быть использован для идентификации объекта. Потому что это чистый произвол.
4. Меня не интересует идентификация картофелины.
Можно я тоже поучаствую в вашей беседе?
Идея эквивалентности по внутренней структуре состоит в том, что объекты с одинаковой структурой (читай, типом) и наполнением этой структуры считаются эквивалентными.
Можно найти аналогию в реляционных БД.
Если у вас две записи в одной таблице с идентичным наполнением полей, то вы не сможете их отличить.
Введение суррогатного первичного ключа (не отвечающего физическому смыслу сущности) не только не решает проблемы, но делает её ещё хуже — это верный путь к дублированию сущностей и нарушению целостности.
Аналогом суррогатного ПК в ОО является адрес (ссылка) объекта.
Если объект отличается от другого объекта только адресом, то как вы поймёте какой из программных объектов соответствует какому реальному объекту?
В вышеприведённой ситуации с коробками вводится идентификационный номер коробки, который должен быть набит на реальной коробке.
Иначе кладовщик не согласится работать как материально ответственное лицо ни под каким соусом.
Либо он находит в этом хороший способ к усушке-утруске-уворовке :)
Вы отлично написали, просто не в бровь, а в глаз.
Только сложно убедить того, кто не пользовался этим.
Об этом писал Грэм в Beating the Averages про гипотетического программиста на Blub.
То же и про кольцевой буфер.
Конкретные реализации дают выигрыш в конкретных случаях.
Про бесплатный сыр никто не говорил и не ожидал.
Менторский тон заключительной фразы не способствует приятному обсуждению.
Классикой написания на хаскелле считается выведение всех операций ввода-вывода в отдельные функции и тем самым получение в остальной программе чисто функционального стиля.
Чем же хуже вариант с выведением в отдельные функции операций, оптимизирующих работу с памятью и другими ресурсами?
Там в конце даже тесты производительности, вполне достойные.
Просто не знаю как уже донести эту мысль (которая здесь и другими участниками высказывалась), что для производительности можно выделять память из пула.
Уж не напоминаю, что в самой статье тема производительности тоже затрагивалась, причём с однозначным ответом на этот вопрос.
Внутри MemoryManager.GetMat может быть, например, кольцевой буфер.
Или дерево с ссылками на свободные chunkи памяти.
Или что угодно, что может оперировать с _предвыделенными_ областями памяти.
Единственная задача — предоставить абстракцию, чтобы в этот логический блок памяти записывались данные только для матрицы dst, и не записывались никакие другие.
Принципиальная реализация не важна.
Вы лучше скажите почему «выделение» — это всегда выделение.
Может я что-то неправильно понимаю в ваших словах.
{
Mat dst = MemoryManager.GetMat(sizeof(src));
dst = map (src, filter2Dfunc);
return dst;
}
Ну вот, например, как здесь C++: Custom memory allocation
(И это я ещё не вспоминаю о том, что автор статьи явно указал, что пишет не о проблемах производительности :))
Можно вручную, а можно предусмотреть и автоматическую сборку мусора (которая, можно сказать, из FP родом).
Просто вы говорите, что выделение памяти на каждый вызов функции затормаживает обработку, поэтому надо выделять заранее буфер и всё время его передавать в функцию, чтобы сэкономить на операции выделения памяти.
А я говорю, что скорость выделения может быть очень высока и этим можно пренебречь.
1. Выделение памяти ведёт к снижению производительности
2. Написать в функциональном стиле без выделения памяти невозможно
Отсюда вывод: написать в функциональном стиле без снижения производительности невозможно.
Но здесь «выделение памяти» в этих двух пунктах может иметь разное значение.
Даже в самом кошерном ОО С++ если нужна сверхскорость при работе с объектами, начинают переопределять new() с использованием нестандартных аллокаторов.
Кто мешает написать функцию ФП с «выделением» памяти, которое на самом деле будет просто возвращать ссылку на область памяти из предвыделенного пула?
2. А вы задумывались, что я не говорил, что суррогатные ключи — это зло?
3. Что мешает назвать первую коробку второй, а вторую первой?
4. Какое это имеет отношение к картофелинам?
2. Так в чём плюс неизменности номера пенсионного? Особенно если учесть, что он никак не привязан к объекту, кроме произвольной договорённости.
3. Вам ничто не мешает в таком случае завести два и более объектов, соответствующих одному объекту реального мира. Опять же в реляционных БД для отношения (моделирующего объекты реального мира) с искуственным первичным ключом обязательно должен быть определён альтернативный уникальный ключ. Иначе неминуемо нарушение целостности и коллизии.
2. Это я даже не понял.
3. О чём и речь — и именно поэтому порядковый номер, если он не является свойством коробки, как объекта реального мира, не может быть использован для идентификации объекта. Потому что это чистый произвол.
4. Меня не интересует идентификация картофелины.
Идея эквивалентности по внутренней структуре состоит в том, что объекты с одинаковой структурой (читай, типом) и наполнением этой структуры считаются эквивалентными.
Можно найти аналогию в реляционных БД.
Если у вас две записи в одной таблице с идентичным наполнением полей, то вы не сможете их отличить.
Введение суррогатного первичного ключа (не отвечающего физическому смыслу сущности) не только не решает проблемы, но делает её ещё хуже — это верный путь к дублированию сущностей и нарушению целостности.
Аналогом суррогатного ПК в ОО является адрес (ссылка) объекта.
Если объект отличается от другого объекта только адресом, то как вы поймёте какой из программных объектов соответствует какому реальному объекту?
В вышеприведённой ситуации с коробками вводится идентификационный номер коробки, который должен быть набит на реальной коробке.
Иначе кладовщик не согласится работать как материально ответственное лицо ни под каким соусом.
Либо он находит в этом хороший способ к усушке-утруске-уворовке :)
Тогда может лучше TransferMoneyFrom (account, toAccount, sum)?
Я имел в виду, что я для развлечения пишу на spoj (тоже проекты ведь), а у вас они чем практичны, то есть, какая польза от них?