- PVSM.RU - https://www.pvsm.ru -

Релиз Go 1.7

Сегодня, 16 августа 2016, вышел восьмой стабильный релиз языка программирования Go — Go 1.7 [1]. Как обычно, релиз выпущен по намеченному плану, через пол года после предыдущего, и в нём нет обратно несовместимых изменений. В тоже время, в Go 1.7 довольно много новых и важных изменений, уменьшены время компиляции и размеры бинарников, увеличена скорость работы и в стандартную библиотеку наконец-то добавлен пакет context. Под катом более подробный обзор новшеств и нововведений.

Новый SSA бекенд

Пожалуй, одним из важнейших изменений в этом релизе является использования нового бекенда компилятора, поддерживающего SSA [2]-форму (Static Single-Assigment). Переход на SSA-бекенд даёт новые возможности для оптимизации и генерации более эффективного кода, и это уже можно наблюдать в данном релизе.

Чтобы сравнить результат компиляции старого и нового бекенда, достаточно передать параметр команде go build:

go build -gcflags="-ssa=0"

и для нового (SSA включён по-умолчанияю в Go 1.7).

go build

Переход на новый бекенд уже сейчас даёт прирост в скорости программ от 5 до 35%.

Также можно покопаться в коде, генерируемом бекендом, с помощью переменной GOSSAFUNC:

GOSSAFUNC=main go build && open ssa.html

Релиз Go 1.7 - 1

Новый формат метаданных

Хотя это изменение абсолютно невидимо для простых пользователей, его стоит упомянуть. В Go 1.7 используется новый формат экспорта метаданных в бинарных файлах, более компактный и эффективный, чем предыдущий. Он исправляет некоторые залежавшиеся баги и генерирует бинарные файлы меньшего размера. Его можно отключить параметром -newexport=0

go build -newexport=0

Поддержка MacOS X 10.12 'Sierra'

Хотя мы привычно ожидаем, что бинарники собранные с прыдыдущими версиями Go будут работать во всех будущих версиях различных OS — в случае с ещё не вышедшей MacOS X 10.12 это не так. В этом релизе MacOS была изменена реализация системного вызова gettimeofday(), а в Go, фактически используется копия её реализации, поэтому при её изменении в ядре, пришлось изменить код и в Go. Как это можно отразиться на практике — бинарники под MacOS X собранные с Go < 1.6.3 не будут корректно работать на MacOS X 10.12 'Sierra'. Если вы распространяете в бинарниках, убедитесь, что собираете их с Go 1.6.3 или 1.7, чтобы они корректно работали на MacOS X 10.12.

Оптимизация и ускорение компилятора и линкера

Помимо вышеупомянутых пунктов, оптимизации подверглось много компонентов стандартной библиотеки, компилятора и линкера, в результате чего бинарники должны быть меньше в размере на 20-30%, а код должен работать гораздо быстрее (особенно на x86-64 платформах), чем Go 1.6. При этом, благодаря новому бэкенду, остается еще много пространства для запланированных оптимизаций на следующие релизы.

Также в некоторых пакетах стандартной библиотеки оптимизации добавили более чем 10% ускорение — crypto/sha1, crypto/sha256, encoding/binary, fmt, hash/adler32, hash/crc32, hash/crc64, image/color, math/big, strconv, strings, unicode и unicode/utf16.

Также в программах с большим количеством запущенных горутин паузы сборщика мусора должны намного меньше.

Context

Одним из самых ожидаемых добавлений в стандартную библиотеку был перенос пакета golang.org/x/net/context в context [3]. Из имени было убрано слово "net" потому что, хотя context и используется чаще всего в коде, работающим с запросами из сети, но его функционал не ограничен только работой с сетью. К примеру, он может использоваться для os/exec и других вещей.

Почему это важно? В Go появилось немало http-фреймворков и пакетов, задача которых была обеспечить передачу контекста внутри обработчиков входящих запросов. net/context постепенно начал занимать эту нишу, но теперь, с context в стандартной библиотеке и с нативной его поддержкой в пакетах net, net/http и os/exec, писать код, работающий с контекстами запроса будет гораздо проще и унифицированней.

В пакете net [4] появился новый метод типа Dialer [5]:

func (d *Dialer) DialContext(ctx context.Context, network, address string) (Conn, error)

Если таймаут контекста истекает раньше, чем произошло установление соединения, DialContext возвращает ошибку.

В net/http [6] в типе Request [7] появились методы Context() [8] и WithContext() [9]:

func (r *Request) Context() context.Context

func (r *Request) WithContext(ctx context.Context) *Request

Метод Context() используется для получение контекста запроса, для его изменения используйте WithContext(). В исходящих запросах context теперь управляет отменой запроса.

Vendoring

В этом релизе переменная GO15VENDOREXPERIMENT больше не поддерживается, теперь вендоринг это стандартный функционал тулинга Go.

Testing

В пакете testing, который используется для написания тестов, появилась поддержка вложенных иерархических тестов и бенчмарков. Это бывает очень удобно для BDD-тестирования, табличных тестов и для более компактной организации тестов в целом. Пример кода:

func TestTeardownParallel(t *testing.T) {
    // This Run will not return until the parallel tests finish.
    t.Run("group", func(t *testing.T) {
        t.Run("Test1", parallelTest1)
        t.Run("Test2", parallelTest2)
        t.Run("Test3", parallelTest3)
    })
    // <tear-down code>
}

Детали доступны в документации к пакету: https://golang.org/pkg/testing/#hdr-Subtests_and_Sub_benchmarks [10]

Разное

  • go tool trace теперь не требует бинарник для анализа трейса, и оверхед на трейсинг уменьшился с 400% до 20%
  • в стандартную библиотеку включён простой zipkin-аналог инструмент httptrace — net/http/httptrace/ [11]
  • os/user.Current больше не требует cgo (таким образом, осталось 3 места, где cgo всё ещё используется в стандартной библиотеке)

Полный список изменений доступен тут: https://golang.org/doc/go1.7 [12]

Стоит ли мне обновляться?

Обычно никаких рисков с обновлением на новый релиз нет, и в Go коммьюнити свежая версия используется большинством. Но есть смысл первые пару недель подождать, потестировать билды на 1.7 в тестовом режиме. В последних двух релизах были минорные релизы (1.5.1 и 1.6.1) с исправлениями очень специфических багов, найденных в первые недели после основного релиза.

Ссылки

https://golang.org/doc/go1.7 [12]
https://golang.org/dl/ [1]

PS. В этом релизе приняли участие 170 человек, из которых 140 — не из Google, а из Go сообщества.

Автор: divan0

Источник [13]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/release/173906

Ссылки в тексте:

[1] Go 1.7: https://golang.org/dl/

[2] SSA: https://en.m.wikipedia.org/wiki/Static_single_assignment_form

[3] context: https://golang.org/pkg/context/

[4] net: https://golang.org/pkg/net

[5] Dialer: https://golang.org/pkg/net/#Dialer

[6] net/http: https://golang.org/pkg/net/http/

[7] Request: https://golang.org/pkg/net/http/#Request

[8] Context(): https://golang.org/pkg/net/http/#Request.Context

[9] WithContext(): https://golang.org/pkg/net/http/#Request.WithContext

[10] https://golang.org/pkg/testing/#hdr-Subtests_and_Sub_benchmarks: https://golang.org/pkg/testing/#hdr-Subtests_and_Sub_benchmarks

[11] net/http/httptrace/: https://golang.org/pkg/net/http/httptrace/

[12] https://golang.org/doc/go1.7: https://golang.org/doc/go1.7

[13] Источник: https://habrahabr.ru/post/307864/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best