Знакомимся с совместимостью Swift и C++
Развлекаемся с экспериментальными функциями swift toolchain.
Вступление
Swift - очень удобный язык, хотя и у него есть свои причуды и своеобразная нелинейность обучения. Тем не менее, с его помощью вы можете довольно быстро выпустить готовый к работе код. Как бы то ни было, иногда у вас возникают чувствительные к производительности разделы, и Swift не очень помогает сократить их количество. В таких случаях популярным выбором становится использование языка C++.
И тут возникает вопрос: "как вызвать С++ функцию через Swift"? Чтобы сделать такой вызов, зачастую вам нужно будет написать оболочку Objective-C, которая будет выступать в качестве публичного интерфейса для вашего кода на C++. В подобных случаях Swift toolchain может помочь импортировать код Objective-C в Swift. Основное ограничение этого метода заключается в том, что вы не сможете использовать классы C++ в Objective-C, только простые POD-структуры.
Мы напишем сито алгоритма Эратосфена как на C++, так и на Swift. Затем узнаем, как активировать совместимость с C++ и вызвать код C++ из Swift, а за одно сравним производительность этих реализаций. Имейте в виду, что эта режим совместимости является экспериментальной функцией и она может быть в любой момент изменена. Данная статья писалась на версии Xcode 14.2.
Алгоритм
Сито Эратосфена находит все простые числа, меньшие или равные N. Простое число — это целое число, которое делится только на себя и на 1. Алгоритм создает логический массив, чтобы определить, является ли каждое число простым. Далее он постепенно перебирает их, помечая все кратные как не простые.
Вот реализация алгоритма на Swift.
Для реализации на C++ нам нужен заголовок и исходный файл. Обратите внимание, что мы ввели typedef, чтобы иметь более чистое имя для обращения к std::vector<long>.
Структура проекта
Мы создадим контейнер/package Swift с двумя отдельными targets - для хранения нашего кода Swift и C++. Чтобы импортировать код C++ из Swift, нам нужна карта модуля.
Не забудьте передать enable-experimental-cxx-interop в Package.swift в swift targets
Обратитесь к документации от Apple, если вы хотите более подробно узнать о том, как включить совместимость с C++.
Тестируем результаты
Гораздо удобнее и проще использовать наш VectorLong из swift в соответствии с RandomAccessCollection.
Теперь мы можем вызвать нашу С++ функцию из swift и вывести результат в консоль.
А теперь давайте проверим будет ли наша реализация на С++ работать быстрее.
Мы видим, что производительность на С++ в среднем чуть быстрее, 26 секунд на C++ против 28 cекунд на swift.
Заключительные мысли
Мы смогли напрямую использовать std::vector в Swift. Лично я не нашел удобного способа переключения между Swift Map и std::map, Set и std::set. Тем не менее, совместимость swift c C++ быстро развивается, и будущее этой совместимости вселяет оптимизм.
Папка CppInteroperability в репозитории Swift содержит дополнительную информацию о функциях взаимодействия, ограничениях и дальнейших планах.
С полным кодом можно ознакомиться по адресу https://github.com/ksemianov/SwiftCXXInteropExample
Вступай в открытый чат для iOS-разработчиков: t.me/swiftbook_chat