время компиляции и время выполнения шаблонов Hamlet

Что касается механизма шаблонов Hamlet, я понимаю, что шаблон анализируется во время компиляции, что приводит к исходный код, содержащий вызовы комбинаторов blaze-html (и, возможно, других выражений из-за интерполяции). Таким образом, точки (поддеревья), в которых происходит интерполяция, известны во время компиляции.

Во время выполнения нам нужно вычислить интерполированное значение (разумеется) и «вставить» его в дерево, то есть применить комбинаторы html. Все они? На самом деле некоторые из этих приложений могут быть оценены во время компиляции (те, которые не имеют интерполяции под ними). Это случается?


person d8d0d65b3f7cf42    schedule 08.06.2015    source источник


Ответы (3)


Прошло некоторое время с тех пор, как я работал над кодом, поэтому не принимайте это как авторитарное (как упомянул Дэниел, -ddump-simpl здесь хороший вызов). Но я не верю, что мы используем комбинаторы blaze-html, только тип данных. Сам Hamlet максимально объединяет строки во время компиляции, чтобы избежать этих затрат во время выполнения. Я знаю, что когда я в последний раз проводил бенчмаркинг (это было много лет назад), эта оптимизация окупилась довольно хорошо.

person Michael Snoyman    schedule 09.06.2015

Вероятно, нет: то, о чем вы просите, очень похоже на частичную оценку (не путать с частичным приложением), что является чем-то вроде минного поля производительности компилятора, поэтому его часто избегают. Но вы можете проверить сами; используйте -ddump-simpl с предпочтительным уровнем оптимизации, чтобы увидеть ядро, которое генерирует GHC.

person Daniel Wagner    schedule 09.06.2015
comment
Обратите внимание, что речь идет о времени компиляции, а не о компиляторе (упростителе ghc). Мы запускаем код шаблона haskell, который может выполнять упрощения для предметной области (и это происходит, см. пример ниже). - person d8d0d65b3f7cf42; 09.06.2015

как говорит Майкл: «Гамлет сам максимально объединяет строки во время компиляции, чтобы избежать этих затрат во время выполнения».

На примере из книги

main = putStrLn $ renderHtml [shamlet|
<p>Hello, my name is #{name person} and I am #{show $ age person}.
<p>
    Let's do some funny stuff with my name: #
    <b>#{sort $ map toLower (name person)}
<p>Oh, and in 5 years I'll be #{show ((+) 5 (age person))} years old.
|]
  where
    person = Person "Michael" 26

-ddump-simpl содержит это:

               (>>
                  @ Text.Blaze.Internal.MarkupM
                  Text.Blaze.Internal.$fMonadMarkupM
                  @ ()
                  @ ()
                  (id
                     @ (Text.Blaze.Internal.MarkupM ())
                     (. @ Data.Text.Internal.Text
                        @ Text.Blaze.Internal.Markup
                        @ String
                        Text.Blaze.Internal.preEscapedText
                        Data.Text.pack
                        (GHC.CString.unpackCString#
                           ".</p>\n\
                           \<p>Let's do some funny stuff with my name: <b>"#)))

Действительно, это не синтаксическое дерево HTML (последняя строка - строка содержит закрывающий тег и следующий открывающий тег).

Эту гамлетовскую черту надо больше рекламировать!

person d8d0d65b3f7cf42    schedule 09.06.2015