В Julia, почему @printf - это макрос, а не функция?
В Julia синтаксис для печати отформатированной строки выглядит следующим образом:
@printf("Hello %d\n", 5)
Почему @printf
макрос вместо функции? Это так, что он может принять различное количество аргументов?
2 ответа
Принятие переменного количества аргументов не является проблемой для нормальных функций Джулии [ 1]. @printf
является макросом, так что он может анализировать и интерпретировать строку формата во время компиляции и генерировать пользовательский код для этой конкретной строки формата. Люди могут не понимать, что С printf
функция повторно анализирует и интерпретирует строку формата каждый раз, когда вы вызываетеprintf
, Факт, что это так же быстро, как это представляет незначительное чудо безумного программирования указателя. Серьезно, просто посмотри на ближайшую библиотеку printf
реализация. Это совершенно чокнутый.
Юлия использует другой подход: @printf
это макрос, который переводит строки формата в эффективный код, специфичный для этой спецификации формата. Если вы подумаете об этом, строка формата в стиле printf - это просто способ выражения функции, которая принимает фиксированное число и тип аргументов и печатает их определенным образом. Обратите внимание, что я сказал, что строка формата - это функция, а не сам printf, который концептуально является генератором функций, превращающим форматы в форматтеры. Тот факт, что все это встроено в функцию времени выполнения в C, является небольшим несоответствием из-за того, что это единственный разумный вариант в C. На самом деле, из-за этого до недавнего времени было довольно легко застрелить себя в ноге, передав неправильный номер или тип аргументов в printf Си. Теперь это только лучше, потому что компиляторы специально разбираются в семантике форматов printf.
Теоретически, Юлия @printf
может быть сделан быстрее, чем C, поскольку он генерирует пользовательский код, но на практике мне было достаточно сложно сопоставить C, не говоря уже о том, чтобы победить его. Но я думаю, что это связано с текущим дизайном нашей системы ввода-вывода и с тем, как я его использую, а не с внутренним ограничением. Тем не менее, ввод-вывод требует капитального ремонта, и когда это произойдет, мы сможем превзойти C при форматированной печати, используя тот факт, что @printf
это макрос.
Это для производительности. printf
макрос принимает постоянную строку формата (например, "Hello %d\n"
) и генерирует оптимизированный код для этой строки.