Cgo довольно медленный, потому что Go имеет mess with its runtime and calling conventions определенным образом для вызова функций C. Единственное место, в котором это действительно стоит, - это случаи, когда время вычисления значительно затмевает this cost. Он похож на параллельный, распределенный, графический процессор и т. Д. Программирование, хотя и с несколько меньшими затратами на запуск.
Сборка намного лучше, потому что вы можете написать сборку, которая использует соглашение о вызове Go, и в противном случае рассматривается как собственный код Go, но сборка гораздо менее переносима, сложнее для чтения и больше обслуживания. Фактически, стандартная библиотека Go записывает некоторые из пакетов math
и big
в сборке Plan 9.
Gonum является примером обоих из них. Он использует общую сборку для некоторых функций, которые могут быть выполнены более быстро таким образом, но в ней также используются механизмы blas и lapack. Он обеспечивает реализацию Go-blas
, но C-blas (обычно это, в конечном счете, Fortran-blas) работает быстрее, а для больших вычислений матрицы почти всегда затмевает стоимость ухода Go.
Как правило, вы хотите избежать cgo, когда это возможно. Используйте его только тогда, когда требуется значительное время вычисления, или вам нужно взаимодействовать с вещами, которые были бы нетривиальными для взаимодействия с чистым Go, например с графическими или аудиодрайверами, или для доступа к общим библиотекам, таким как OpenCV. Даже тогда, если вы действительно заботитесь о производительности, там, где это возможно, возможно, стоит реализовать какой-то «пул вызовов», где вы можете запланировать несколько вызовов со стороны Go и выполнить их все сразу с помощью одного контекстного переключателя на C.
Редактировать: Что касается C++, есть некоторые существенные проблемы. Трудно обернуть некоторые библиотеки без нескольких слоев абстракции (так как cgo не может правильно обрабатывать заголовки C++). Кроме того, классы C++ с деструкторами не могут быть действительно возвращены по значению и должны быть выделены в кучу. Так как Go не позволяет детерминировать окончательную доработку ресурсов, вы должны , чтобы предоставить функцию для явного освобождения памяти, и пользователь Go должен помнить о том, чтобы освободить ресурс.(Существует функция, которую вы можете прочитать в документации под названием runtime.SetFinalizer
, но я не могу сказать, что я когда-либо видел, чтобы кто его использовать, а сама документация поставляется с кучей оговорок)
такие функции, как defer
делает это более управляемым, но он разрушает много вещей, таких как RAII, которые делают современные методы C++ более безопасными.
Скорее всего, только для повторного использования. Почти каждая основная библиотека (не говоря уже о ОС) имеет привязку C, поэтому возможность вызова C с вашего языка является большой победой для принятия языка. – Dan