Как автоматически преобразовать чистый код в код, который использует изменяемые массивы для эффективности? - PullRequest
5 голосов
/ 22 мая 2011

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

В Haskell сгенерированный код будет либо выполняться вST монада (в этом случае все это будет обернуто в runST или runSTArray) или в IO монаду, я полагаю.

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

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

Ответы [ 2 ]

4 голосов
/ 22 мая 2011

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

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

Несколько языков, включая Сизаль и SAC, попытка повторно использовать старую память массива для хранения новых массивов.В SAC программы сначала преобразуются для использования явного управления памятью (в частности, подсчета ссылок), а затем оптимизируется код управления памятью.

0 голосов
/ 22 мая 2011

Вы говорите «либо списки, либо неизменяемые массивы», но на самом деле это две совершенно разные вещи, и во многих случаях алгоритмы, естественным образом подходящие для списков, не будут быстрее (и, возможно, медленнее) при использовании с изменяемыми массивами.

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

Изменяемые массивы, скорее всего, будут полезны при выполнении множества частичных обновлений произвольного доступа к массиву без очевидной линейной структуры. При использовании неизменяемых массивов Haskell во многих случаях это можно выразить с помощью функции accum в Data.Array, которая, как я считаю, уже реализована с использованием ST.

Короче говоря, во многих простых случаях либо доступны лучшие оптимизации, либо они уже обработаны.

Редактировать: Я заметил, что этот ответ был отклонен без комментариев, и мне любопытно, почему. Обратная связь приветствуется, я хотел бы знать, сказал ли я что-то глупое.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...