Go для Web

в 12:15, , рубрики: php, web, метки: ,

Где-то читал высказывание разработчиков самого языка что он изначально разрабатывался не для Веб программирования а немного для других областей применения, однако, сейчас в нём вроде бы есть всё для использования в Веб программировании, и многие присматриваются к нему сопоставляя php vs Go, node.js vs Go.

Всякая система производительна на столько, насколько производительно её самое слабое звено. Какое же слабое звено у Go в Web? Go язык компилируемый со строгой! типизацией, в нём нет автоматического приведения типов. Зачастую в публикациях встречаются сопоставления производительности языков программирования где в качестве тестов используются: построить ряд Фибоначчиб, ряд простых чисел и подобные им вычислительные задачи. Разумеется такие задачи не слабая сторона языка Go. Слабая его сторона является тенью от его сильной стороны, которая, на практике падает на многие задачи характерные для Веба.

Вывод, шаблонизация, импортно/экспортные операции всё это есть в Go (в Go уже есть стандартный пакет шаблонизации), однако это всё есть через одно место… через отражения (reflection). Отражения это такой механизм, используя который программа способна изучать сама себя и на основе полученной информации модифицировать сама себя, то-есть она этим занимается как бы разглядывая себя в отражении.

Как эта штука реализована в Go. В языке существует механизм приведения типов (type assertions) v, ok = x.(MyType), утиная типизация и универсальный тип (пустой интерфейс) interface{} которому можно сопоставить переменную любого типа. Итак мы можем впихнуть свои данные в переменные типа interface{}, теперь, как их оттуда извлечь. Если нам известен тип переменной то мы просто выполняем операцию приведения типа, если нет, то в языке существует 2 способа узнать тип переменной:

Переключатель на основе типов

switch type_value:= value.(type) {
case int:
case []int:
case string:
case []string:
case MyType:
       type_valu.item1 = 1   
... и тд.
}

Такая вот конструкция обращения к типу переменной value.(type) возможна только в switch, где-либо ещё её вызвать невозможно. Переключатель на основе типов является, судя по всему, всего лишь обёрткой и синтаксическим сахаром основного механизма — механизма рефлексии, то есть отражения.

Прямое обращение к механизму отражения

Доступ к функциям которого осуществляется посредством подключения пакета reflection. Мы можем посмотреть в отражение на переменную и узнать её тип и… и всё, казалось бы — узнали тип, тут же привели к нему и работай, ан нет, не всё так просто, узнать то тип мы узнали, но узнали мы его в терминах отражения и работать с переменной можем только через механизмы отражения, которые, мягко говоря, не особо удобны это раз, не особо производительны это два.

Везде, во всех компонентах использующих отражения: пакет форматированного вывода («fmt»), шаблонизация («html/template», «text/template»), кодирование/декодирование («encoding/json» и прочие) и прочие, стоит ожидать падения производительности в сопоставлении с языками с динамической типизацией.

В функции которая принимает две переменных и возвращает их конкатенацию накладные расходы на приведение типов в сопоставлении с нативной функцией составляют около 12%

func(a, b string) string
func(a, b interface{}) string

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

В тестовом примере сопоставления производительности кодирования объектов в json Go проигрывает PHP более чем в 5 раз.

Материалы:
Отражения (ру) http://ru.wikipedia.org/wiki/Отражение_(программирование)
Go laws of reflection (en) http://blog.golang.org/laws-of-reflection
проведённые тесты https://github.com/Cergoo/go_benchmark

Автор: Cergoo

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js