OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Четверг, 28 Март, 2024 21:23

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 33 ]  На страницу 1, 2  След.
Автор Сообщение
СообщениеДобавлено: Вторник, 04 Декабрь, 2018 01:07 

Зарегистрирован: Понедельник, 11 Сентябрь, 2017 13:23
Сообщения: 1557
Зачем только указатели?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 04 Декабрь, 2018 04:37 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 3774
Как я это понимаю, где-то могу быть неточен терминах. Есть два места где ББ хранит информацию, в стеках вызова процедур и в куче. Так что возврат аргументов массивов или записей будет использовать не кучу, а именно стек, и это плохо, тем что раздутие стека может легко привести к переполнению оперативной памяти. Особенно при рекурсивных алгоритмах. Поэтому тут язык провоцирует использовать хороший стиль повторного использования структур в RAM.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 04 Декабрь, 2018 10:20 

Зарегистрирован: Понедельник, 11 Сентябрь, 2017 13:23
Сообщения: 1557
Да, такой возврат должен использовать стек. Но ведь если мы передаём запись по значению в качестве параметра, или даже заводим локальную переменную типа запись - она тоже должна быть в стеке.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 04 Декабрь, 2018 10:58 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9459
Откуда: Россия, Орёл
Потому что оптимально всегда возвращать запись и массив по ссылке (через VAR, OUT-параметры).
Через стек копировать - неоптимально.

Языки, которые позволяют такое, потом вынуждены заниматься оптимизацией (реально return гнать через связывание адресов какое-то при вызове). Что есть корявое нагромождение, ради непонятно каких выгод.

Да, на 64-битной архитектуре скопировать небольшую запись или даже строку (до 128 байт) может быть чуть быстрее, чем сходить по ссылке.

В стиле кодирования в моей команде я ввёл подчёркивание выходных и VAR-параметров в точке вызова. Очень легко читается тогда, что меняет вызов, а что принимает как вход.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 04 Декабрь, 2018 11:00 
Аватара пользователя

Зарегистрирован: Вторник, 28 Август, 2007 00:55
Сообщения: 520
Откуда: Украина, Днепропетровская обл.
Записи и массивы возвращать можно и нужно — для этого используются VAR-параметры. Было Оберон-расширение, в котором делалась попытка представить возврат сложно-составного результата прямо по RETURN. Это расширение называется Oberon-X. Но ничего семантически нового в этом нет, просто сахар. Ну какая разница — вот так написать:

Код:
PROCEDURE Proc (): ARRAY OF CHAR;
или вот так:
Код:
PROCEDURE Proc (VAR result: ARRAY OF CHAR);


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 04 Декабрь, 2018 11:05 
Аватара пользователя

Зарегистрирован: Вторник, 28 Август, 2007 00:55
Сообщения: 520
Откуда: Украина, Днепропетровская обл.
А разница всё-таки есть! Во втором случае мы работаем с готовой структурой, переданной нам извне по ссылке. А в первом — мы сами формируем новую структуру внутри процедуры и отдаём её в виде результата, который потом надо скопировать в ещё одну принимающую структуру. Чувствуете разницу по накладным расходам?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 04 Декабрь, 2018 11:22 

Зарегистрирован: Понедельник, 11 Сентябрь, 2017 13:23
Сообщения: 1557
Я вас понял, но не скажу, что согласен. Та же фигня будет, например, с LONGINT - он тоже не помещается в машинное слово. Не скажу, что я уверен на 100%, что возврат будет сложнее, чем передача по параметру, но вроде похоже на правду.

Даже если так, возврат значения любого типа, может быть, имеет свою цену при реализации компилятора, но зато он удобен. А так - избежали одного костыля в компиляторе, и вместо этого запустили фабрику «медтехника» для пользователей. Если я хочу вернуть запись из функции, я должен завести именованную переменную или пользоваться указателями, или кучей. В коммандерах тоже трудности возникают.

Ну и главное - мы не можем использовать ФП парадигму, которая достаточно полезна. Её использование вынуждает нас городить указатели там, где без них можно было обойтись).


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 04 Декабрь, 2018 11:33 

Зарегистрирован: Пятница, 13 Март, 2009 16:36
Сообщения: 987
Откуда: Казань
budden писал(а):
Ну и главное - мы не можем использовать ФП парадигму, которая достаточно полезна. Её использование вынуждает нас городить указатели там, где без них можно было обойтись).

Вы сами ответили на свой вопрос. Просто используйте указатели и возвращайте что хотите.
Функциональные языки внутри себя примерно так и реализованы.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 04 Декабрь, 2018 12:07 

Зарегистрирован: Понедельник, 11 Сентябрь, 2017 13:23
Сообщения: 1557
Пользоваться указателями - ну, тут мы приходим к ещё одному вопросу, который для меня довольно неприятен. В лиспе, свифте, окамле, хаскеле, яве нет разделения на "записи" и "указатели". Оно, может быть, где-то на периферии есть, но его стараются выдавить подальше от центра. Я не хочу две сущности, хочу одну. Не скажу, что мне нравится, как это решено в других языках, но подход лиспа мне ближе всех. Любая переменная и любой параметр семантически являются указателями. Но некоторые типы являются иммутабельными и не имеют идентичности, поэтому для них нет разницы между передачей указателя и передачей копии значения.

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

Если я хочу писать на КП в ФП стиле, у меня резко растёт нагрузка на кучу. Это плохо для отзывчивости приложения, Эклипс все видели, я думаю :)

Другой подход у свифта - структуры передаются только по значению. Применяетcя ленивое копирование, т.е. объект фактически копируется только в момент изменения. Внутри опять же могут быть (а могут и не быть) указатели. Но снаружи язык выглядит простым. Правда, мне этот подход не нравится, может быть, я просто что-то недопонял.

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


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 04 Декабрь, 2018 12:30 

Зарегистрирован: Вторник, 26 Январь, 2010 09:31
Сообщения: 717
Откуда: Барнаул
В возврате по значению нет особых проблем. Например, в Активном Обероне можно возвращать по значению, причина очевидна - многопоточка, где нужны гарантированно немутабельные данные ( для данного конкретного состояния ).
Но Вирт решил, что передача по значению это зло, вот оно в КП и отсутствует. Что касается производительности, то код с передачей по значению может быть, как-раз, производительней, ибо исключает указатели.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 04 Декабрь, 2018 12:36 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9459
Откуда: Россия, Орёл
2budden:

А Вы видели ФП (особенно во всяких ленивых вариациях) без дикой нагрузки на кучу??


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 04 Декабрь, 2018 12:55 

Зарегистрирован: Понедельник, 11 Сентябрь, 2017 13:23
Сообщения: 1557
Kemet писал(а):
Что касается производительности, то код с передачей по значению может быть, как-раз, производительней, ибо исключает указатели.

Ну я так понял, проблема реальна - если мы возвращаем значение, то оно находится на стеке (неизвестно где). А принимающая переменная находится в кадре стека вызывающей функции. Т.е. может понадобиться ещё одно копирование. Хотя... и пре передаче параметра тоже копирование одно. Не пытались ли меня надурить? :D Или всё же при передаче нужно одно копирование, а при возврате - два? Я запутался...

Но даже если так, понятно, что программист должен понимать цену. Если цена состоит в одном лишнем копировании, то есть и случаи, где её можно заплатить. Понятно, что возвращать по значению нужно только маленькие данные.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 04 Декабрь, 2018 13:44 

Зарегистрирован: Понедельник, 11 Сентябрь, 2017 13:23
Сообщения: 1557
Илья Ермаков писал(а):
2budden:

А Вы видели ФП (особенно во всяких ленивых вариациях) без дикой нагрузки на кучу??

Я не такой любитель ФП. Но в общем-то чистое ФП - это скорее про стек, чем про кучу. Куча возникает вместе с глобальными коллекциями, или с мутабельностью. А чистое ФП не имеет состояния и мутабельности. Хотя тут ещё можно долго вдаваться в терминологию и блистать знаниями или отсутствием таковых. Про ленивость можно было бы говорить, если бы мы её собирались делать или если бы она была в КП, но её нет, поэтому и обсуждать нечего.

Но лучше всего разобрать вопрос, что конкретно мешает эффективному возврату по значению из функции, т.е. чем оно хуже, чем передача той же записи в качестве параметра. Мне начинает казаться, что ничем.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 04 Декабрь, 2018 15:08 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 3774
Хочу сказать одно последнее. За 10 лет использования Блэкбокса у меня никогда не было ситуаций утечки памяти. Ни разу. Что-то мне подсказывает, что важную роль в этом играет в том числе отсутствие такой возможности возвращать структуры и массивы в RETURN. Иначе я бы нагородил по неопытности какой-нибудь алгоритм, который сжирал память влет.

Из недавнего опыта использования BlenderCAM. Я запустил расчет траектории фрезы для изготовлении на станке достаточно простой фигуры, и BlenderCAM упал... Небольшое исследование показало, что он в момент, когда я нажимаю кнопку "Расчитать путь" начинает жрать память так жадно, что на моём новом ноуте 6 Гб памяти не хватает, и приложение падает, если отключен файл подкачки. С файлом подкачки расчет таки завершается успешно. То есть для какого-то вшивого расчета как вырезать кружок с пятью отверстиями Блендеру надо больше 4 Гб оперативки... вот это негативный пример, как делать не надо :) в конкретном случае плагин написан на питоне, но он скорее всего дергает ещё какие-то сишные библиотеки.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 04 Декабрь, 2018 15:16 

Зарегистрирован: Понедельник, 11 Сентябрь, 2017 13:23
Сообщения: 1557
Ну, это тут не при чём. В языке со сборкой мусора и не должно быть утечек памяти, если только не начать заполнять какой-нибудь безконечный список. В Питоне сборщик мусора - это дополнительная функция, а так там - подсчёт ссылок. Соответственно, если сборка мусора отключена или плохо настроена, то утечка может возникнуть. Ну и библиотеки на Си, конечно, тоже делают приложение хрупким и глючным.

Но если запись возвращается по значению, то она на стеке - утечь тут нечему. Как раз ровно наоборот.

Ладно, в любом случае нет ресурсов и знаний, чтобы курочить компилятор на таком низком уровне - придётся пользоваться кучей и указателями.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 04 Декабрь, 2018 15:19 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 3774
Ну тут речь не про утечку памяти в примере с Блендером, утечки то как раз может и нет. А про невероятное потребление. Как раз похоже на какой-то рекурсивный алгоритм с хранением данных на стеке.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 04 Декабрь, 2018 15:49 

Зарегистрирован: Понедельник, 11 Сентябрь, 2017 13:23
Сообщения: 1557
Я тут мало что понимаю, но по-моему, такого стека не бывает. Это обычно небольшой кусок памяти фиксированного размера, порядка мегабайт максимум. Может быть, кто-то более знающий поправит.

Хотя вот, SO скорее меня подтверждает : https://stackoverflow.com/questions/182 ... of-program

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


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 04 Декабрь, 2018 16:05 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 3774
Этот вопрос по размеру стека был документирован в сборке Центра не так давно.
https://forum.blackboxframework.org/vie ... f=51&t=730


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 04 Декабрь, 2018 16:14 

Зарегистрирован: Понедельник, 11 Сентябрь, 2017 13:23
Сообщения: 1557
Опять же, не гигобайты, а единицы мегабайт. Но диффы у них красивые, не чета нашим..


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 04 Декабрь, 2018 16:27 

Зарегистрирован: Вторник, 26 Январь, 2010 09:31
Сообщения: 717
Откуда: Барнаул
Проблемы начинаются с головы, а не с языка программирования.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 33 ]  На страницу 1, 2  След.

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 5


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Вся информация, размещаемая участниками на конференции (тексты сообщений, вложения и пр.) © 2005-2024, участники конференции «OberonCore», если специально не оговорено иное.
Администрация не несет ответственности за мнения, стиль и достоверность высказываний участников, равно как и за безопасность материалов, предоставляемых участниками во вложениях.
Без разрешения участников и ссылки на конференцию «OberonCore» любое воспроизведение и/или копирование высказываний полностью и/или по частям запрещено.
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB