Вопрос

В следующей программе удаляем строку

    (declare (type (simple-array bit) arr))

увеличивает время работы более чем в 3 раза при использовании SBCL.Информация о типе, указанная в defclass макрос через :type с другой стороны, похоже, не оказывает никакого влияния на производительность.

(defclass class-1 () ((arr :type (simple-array bit))))

(defun sample (inst)
  (declare (type class-1 inst))
  (let ((arr (slot-value inst 'arr)))
    (declare (type (simple-array bit) arr)) ;; 3x running time without
    (map-into arr #'(lambda (dummy) (if (< (random 1.0) 0.5) 0 1)) arr)))

(let ((inst (make-instance 'class-1)))
  (setf (slot-value inst 'arr) (make-array 10000 :element-type 'bit))
  (loop for i from 1 to 10000 do (sample inst)))

Как я могу получить такой же выигрыш в производительности без необходимости объявлять arr слот а simple-array bit каждый раз, когда я его использую?Последнее особенно раздражает, поскольку (насколько я выяснил) требуется ввести привязку через let или подобное каждый раз;я не могу просто написать (slot-value inst 'arr) в том месте, где мне это нужно.

Это было полезно?

Решение

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

Второй, тебе следует позволить связать arr потому что вы используете его дважды.

Третий, вы можете использовать the если вы хотите избежать let-bind:

(the (simple-array bit) (slot-value inst 'arr))

Четвертый, если вы хотите, чтобы компилятор определил тип, используйте конкретную программу чтения вместо slot-value:

(defclass c () ((arr :type (simple-array bit) :reader c-arr)))

(defun sample (inst)
  (declare (type class-1 inst))
  (let ((arr (c-arr inst)))
    (map-into arr #'(lambda (dummy) (random 2)) arr)))

c-arr должно позволить компилятору легче определить тип значения, но (как вы сами обнаружили!) вам может потребоваться объявить тип возвращаемого значения:

(declaim (ftype (function (c) (simple-array bit)) c-arr))

Причина, видимо, в том, что SBCL игнорирует объявления типов слотов.

Другие советы

Добавление информации о типе имеет разные последствия в зависимости от того, какой компилятор вы используете и какие уровни оптимизации действуют.

Для оптимизирующего компилятора это может выглядеть так:

  • нет информации:общие операции, достаточно быстрые
  • доступно объявление типа:добавлены операции для проверки этого конкретного типа во время выполнения -> медленнее
  • доступны объявления типов, высокая оптимизация и низкая безопасность:НЕТ добавленных операций для проверки типа во время выполнения, для этого типа создается специальный код -> ВОЗМОЖНО БЫСТРЕЕ

Некоторые компиляторы также игнорируют объявления типов для слотов CLOS.Если нет, то снова есть два варианта:1) безопасность означает добавление проверок во время выполнения и 2) низкая безопасность и высокая скорость означает создание специализированных инструкций.

Краткое содержание:объявления типов могут добавить накладные расходы во время выполнения с высокой безопасностью из-за дополнительных проверок типов.Специализированные типы данных не обязательно быстрее, с низкой безопасностью и высокой оптимизацией.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top