Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
Разработка программного обеспечения

Annex: Alternatives

Boost , Chapter 1. Boost.LocalFunction 1.0.0 , Chapter 1. Boost.LocalFunction 1.0.0

Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

PrevUpHomeNext

В этом разделе сравниваются функции, предлагаемые этой библиотекой, с аналогичными функциями, предлагаемыми C++ и другими библиотеками.

Features

В следующей таблице сравниваются локальные функции.

Локальная функция

Повышенный.LocalFunction

C++11 Функция Lambda (не C++03)

Местный функтор

Глобальный функтор (не локальный)

Boost.Phoenix

Может быть определен локально

Да.

Да.

Да.

Следовательно, это не совсем альтернативная реализация локальных функций, но она приведена здесь только для сравнения.

Да.

Может быть определен с использованием синтаксиса С++

Да. Плюс возможные ошибки компилятора и отладка сохраняют привычный смысл и формат.

Да. Плюс возможные ошибки компилятора и отладка сохраняют привычный смысл и формат.

Да. Плюс возможные ошибки компилятора и отладка сохраняют привычный смысл и формат.

Да. Плюс возможные ошибки компилятора и отладка сохраняют привычный смысл и формат.

Нет (используется C++шаблон выражениясинтаксис).

Можно определить в выражениях

Нет. Оно может быть определено только в заявлениях.

Да (плюс локальная функция может быть неназвана).

Нет. Оно может быть определено только в заявлениях.

Нет. Оно может быть определено только в заявлениях.

Да (плюс локальная функция может быть неназвана).

Может передаваться как параметр шаблона (например, в алгоритмы STL)

Да. СтандартC++03не позволяет передавать локальные типы в качестве параметров шаблона (см.[N2657]), но эта библиотека реализует «трюк», чтобы обойти это ограничение (см. разделРеализация).

Да.

Нет компиляторовC++03(но да, компиляторыC++11и некоторые компиляторы, такие как MSVC 8.0, см.[N2657]).

Да.

Да.

Переменные доступа в объеме

Да. Имена переменных повторяются в объявлении функции, так что они могут быть связаны значением, постоянным значением, ссылкой и постоянной ссылкой (объектэтотакже может быть связан с использованиемэто_).

Да. Имена переменных повторяются в объявлении функции (плюс есть краткий синтаксис, связывающий все переменные в объеме одновременно), так что они могут быть связаны постоянным значением и ссылкой (объектэтоттакже может быть связан). Однако переменные не могут быть связаны постоянными ссылками (см. ниже).

No. Программисты должны вручную программировать фанкторы данных и четко указывать их типы для доступа к переменным в объеме.

No. Программисты должны вручную программировать фанкторы данных и четко указывать их типы для доступа к переменным в объеме.

Да. Переменные в объеме доступны как обычно в выражениях (плюсбустер::феникс::пустьможет использоваться для связывания переменных посредством постоянной ссылки).

Полиморфныйв типе параметра функции

Нет (локальные функции не могут быть шаблонами функций).

Нетлямбда C++11не могут быть шаблонами функций.

Нет (местные классы не могут иметь шаблоны функций членов).

Да.

Да.

C++11 Lambda Функция

Функции лямбда C++11имеют большинство функций этой библиотеки плюс некоторые дополнительные функции (см. также пример в разделеВведение):

  • Функции лямбда C++11могут быть определены в выражениях, в то время как локальные функции этой библиотеки могут быть определены только в объеме декларации.
  • Функции лямбда C++11поддерживаются только стандартомC++11, поэтому они не поддерживаются всеми компиляторами C++. Эти локальные функции библиотеки могут быть запрограммированы также на компиляторахC++03(и они имеют производительность, сравнимую сC++11 лямбда-функциямина компиляторахC++11).
  • Функции лямбда C++11не позволяют связывать переменные в объеме постоянной ссылкой. Поскольку переменная не может быть связана постоянной ссылкой, лямбда-функцииC++11могут связывать переменную постоянной только в том случае, если переменнаяCopyConstructibleи для связывания требуется (потенциально дорогостоящая) дополнительная операция копирования. Вместо этого постоянная ссылка поддерживается этой библиотекой.
  • Функции лямбда C++11не позволяют связывать элементы данных выборочно без связывания также объектаэтого, в то время как эти локальные функции библиотеки могут связывать либо выбранные элементы данных, либо весь объектэтого(с использованиемэтого_.
  • Функции лямбда C++11обеспечивают кратковременный синтаксис для связывания всех переменных в объеме одновременно&или=, в то время как эта локальная функция библиотеки всегда требует связывания переменных, именующих их один за другим.

Например, для некопируемых объектов (см. такжеnoncopyable_cxx11_lambda_error.cppиnoncopyable_local_function.cpp):

C++11 Lambda Функция

Повышенный.LocalFunction

повысить[][][][]][20};f();возврат0;]

Или для объектов с дорогостоящими операциями копирования (см. такжедорогой_copy_cxx11_lambda.cppидорогой_copy_local_function.cpp):

C++11 Lambda Функция

Повышенный.LocalFunction

nintinintinti[4 Некоторое время занимает копирование.для[476};f();возврат0;]

струкцияintintint[6 Некоторое время занимает копирование.дляi=0;<;// Зарегистрируйтесь для 'bind&intmainvoidnx[-1voidBOOST_LOCAL_FUNCTIONconstсвязывает&x// OK: Ни один дорогойне утверждаетi==1// копия, но постоянная.}BOOST_LOCAL_FUNCTION_NAMEf]fвозвращают;]

Когда требуется постоянная функциональность связывания для лямбда-функцийC++11, лучшей альтернативой может быть связывание дополнительной локальной переменной, объявленной постоянной и инициализированной к исходной переменной (например, см.постоянные блоки, реализованные слямбда-функциямиC++11 вПримерыраздела).

Местный функтор

Следующий пример сравнивает локальные функции с локальными функторами C++ (см. такжеadd_local_functor.cppиadd.cpp):

Местный функтор

Повышенный.LocalFunction

intvoidintсумма=0,фактор=10;структураlocal_add// К сожалению, код boilerplate для программирования класса.local_addint&_sumint_factor[ Body использует синтаксис C++.сумма+=фактор*Число;}частный:// К сожалению, нельзя связывать так повторяющиеся переменные типы.int&сумма;// Доступ 'сумма' по ссылке.constintфактор;// Сделайте 'фактор' константой.добавьтесумму3[8 К сожалению, не может пройти в качестве параметра шаблона к 'std::for_each'.дляразмер_t=0;2;добавить

intmainvoid// Некоторый локальный объем.intСумма=0,фактор=10;// Переменные в области связывания.пустотаBOOST_LOCAL_FUNCTIONconstbindfactor,bind&sumintintnum]sum+=факторnum;]]]]BOOST_LOCAL_FUNCTION_NAMEдобавить]добавить1;// Вызовите локальную функцию.intnums={2,3std::for_eachnumsnums+2,добавить;// Передайте это алгоритму.BOOST_TESTсумма==60;// Установить итоговое итоговое значение.возвратповышение::отчет_ошибки[;]]

Глобальный функтор

Следующий пример сравнивает локальные функции с глобальными функторами C++ (см. такжеadd_global_functor.cppиadd.cpp):

Глобальный функтор

Повышенный.LocalFunction

// К сожалению, не может быть определено локально (так что не является реальной альтернативой).структурglobal_add// К сожалению, код boilerplate для программирования класса.global_addint&_sumint_factor_ sum_sum_sum_sum_sum[13 Тело использует синтаксис утверждения C++.сумма+=фактор*Число;]частное:// К сожалению, нельзя связывать так повторяющиеся типы переменных.int&sum;// Доступ «сумма» по ссылке.constintintvoidvoid

факторфактор[1316BOOST_TESTсумма==60;возвратповышение::отчет_ошибки[;]]

intmainvoid// Некоторый локальный объем.intСумма=0,фактор=10;// Переменные в области связывания.пустотаBOOST_LOCAL_FUNCTIONconstbindfactor,bind&sumintintnum]sum+=факторnum;]]]]BOOST_LOCAL_FUNCTION_NAMEдобавить]добавить1;// Вызовите локальную функцию.intnums={2,3std::for_eachnumsnums+2,добавить;// Передайте это алгоритму.BOOST_TESTсумма==60;// Установить итоговое итоговое значение.возвратповышение::отчет_ошибки[;]]

Однако обратите внимание, что глобальные функторы не позволяют определить функцию локально, поэтому они не являются реальной альтернативой реализации локальных функций.

Boost.Phoenix

Следующий пример сравнивает локальные функции сBoost.Phoenix(см. такжеadd_phoenix.cppиadd.cpp):

Boost.Phoenix

Повышенный.LocalFunction

std::for_eachnums,nums+3,Let_f=crefфакторК сожалению, тело не может использовать синтаксис утверждения C++.refsum]+=_f*_1_1// Доступ 'сумма' по ссылке.BOOST_TESTсумма==повышениеотчет_ошибки

intmainvoid// Некоторый локальный объем.intСумма=0,фактор=10;// Переменные в области связывания.пустотаBOOST_LOCAL_FUNCTIONconstbindfactor,bind&sumintintnum]sum+=факторnum;]]]]BOOST_LOCAL_FUNCTION_NAMEдобавить]добавить1;// Вызовите локальную функцию.intnums={2,3std::for_eachnumsnums+2,добавить;// Передайте это алгоритму.BOOST_TESTсумма==60;// Установить итоговое итоговое значение.возвратповышение::отчет_ошибки[;]]

Сравнение в этом разделе не включает библиотекуBoost.Lambda, потому что эта библиотека устарела и была замененаBoost.Phoenix. Для этого сравнения используется библиотекаBoost.Phoenixверсии 3.0.

Performances

Следующие таблицы сравнивают время выполнения, время компиляции и двоичные размеры для различных альтернатив локальным функциям, представленным в этом разделе.

В целом, эта библиотека имеет время компиляции и генерирует двоичные размеры, аналогичные тем, которые используются в других подходах. Это время выполнения библиотеки на компиляторахC++03было измерено как большее, чем другие подходы, когда включена оптимизация компилятора (с использованиемbjamrelease...). Однако на компиляторах, которые позволяют передавать локальные типы в качестве параметров шаблона (например, MSVC 8.0 или GCC 4.5.3 с включенными функциямиC++11-std=c++0x, см. также[N2657]иBoost.Config'sBOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS) эта библиотека автоматически генерирует оптимизированный код, который работает так же быстро, как и самый быстрый из других подходов (см. подход «Boost.LocalFunction» ниже). Когда эта локальная функция библиотеки указанаinline(см. ниже подход «Boost.LocalFunction Inline» иРасширенная тематика (раздел 2133) всегда сопоставима с подходами «Локальный функтор» и «Глобальный функтор». Однако в этих случаях локальная функция не может быть переносима в качестве параметра шаблона (см.[N2657]иBoost.Config'sBOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS), поэтомуstd::for_eachзаменяется на for-loop (на MSVC for-loop, а не на локальную функцию фактически то же самое относится к локальным функторам, было измерено, чтобы иметь худшие характеристики, чем использованиеstd::для_each. Наконец, это время выполнения библиотеки всегда является одним из самых быстрых, когда не включена оптимизация компилятора (используяbjamотладка...).

[Note] Note

Производительность времени выполнения этих локальных функций библиотеки объясняется тем, что наC++03совместимых компиляторах (например, GCC 4.5.3 без-std=c++0x) этой библиотеке необходимо использовать указатель функции для переноса локального класса функций в качестве параметра шаблона (см.[N2657]и разделРеализация). Для всех протестированных компиляторов этот указатель функции не позволяет алгоритмам оптимизации компилятора настраивать локальные вызовы функций. Вместо этого были замечены функторы, используемые другими подходами (например,Boost.Phoenix), позволяющие всем тестируемым компиляторам встраивать все функции, требующие оптимизации. Эта стоимость производительности во время выполнения не присутствует на компиляторах, которые позволяют передавать локальные типы в качестве параметров шаблона (например, MSVC 8.0 или GCC 4.5.3 с функциямиC++11, включенными-std=c++0x, см.Boost.Config'sBOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS), потому что эта библиотека не должна использовать дополнительный указатель функции для реализации вызова локальной функции (он непосредственно передает тип локального класса в качестве параметра шаблона).

Эта стоимость исполнения на компиляторахC++03может быть или не быть проблемой в зависимости от требований к производительности конкретных приложений. Например, приложение может уже использовать ряд косвенных вызовов функций (функциональные указатели, виртуальные функции и т.д.), для которых накладные расходы, добавленные с помощью одного дополнительного указателя функций, требуемого локальным вызовом функций, могут быть незаметны в течение общего времени выполнения программы.

Наконец, обратите внимание, что для анаилсиса, представленного здесь, использовался только очень простой локальный функциональный орган с только одной инструкцией (см. исходные файлы ниже). Авторы не изучили, как эта библиотека и другие подходы будут работать по отношению друг к другу, когда более сложный набор инструкций запрограммирован для локального функционального тела (например,, еслиболее сложный набор инструкций в локальном функциональном теле должен был ингибировать некоторый компилятор от встраивания функциональных объектов, а также другие подходы, такие какC++11 лямбда-функциииBoost.Phoenixможет начать показывать более высокие сроки выполнения даже при включенной оптимизации).

Следующие команды были выполнены из каталога примеров библиотеки для измерения времени компиляции, двоичного размера и времени выполнения соответственно:

> touch <FILE_NAME>.cpp                             # force recompilation
> python chrono.py bjam {release|debug} <FILE_NAME> # compile-time
> size <FILE_NAME>                                  # binary size
> ./<FILE_NAME>                                     # run-time

Локальная функция была названа1e8раз, чтобы сложить все элементы вектора, и время выполнения было измерено с использованиемBoost.Chronoв среднем по10исполнений суммирования вектора (см. исходные файлы ниже).

Легенда

Подход

Источник файла

profile_legend_local_function

Boost.LocalFunction

profile_local_function.cpp

profile_legend_local_function_inline

Boost.LocalFunctioninline

profile_local_function_inline.cpp

profile_legend_cxx11_lambda

C++11Функция лямбды[a]

profile_cxx11_lambda.cpp

profile_legend_local_functor

Местный функтор

profile_local_functor.cpp

profile_legend_global_functor

Глобальный функтор

profile_global_functor.cpp

profile_legend_phoenix

Boost.Phoenix

profile_phoenix.cpp

[a]Измерения доступны только для компиляторовC++11.

GCC 4.5.3 Функции C++11 Lambda и «Местные классы как параметры шаблона»bjam cxxflags=-std=c++0x ...

Составлено срелизом бьяма...для максимальной оптимизации-O3 -finline-функции]profile_gcc_cxx11_release

Составлено сотладкой бьяма...без оптимизации-O0 -fno-inline]profile_gcc_cxx11_debug

MSVC 8.0 «Местные классы как параметры шаблона» (без функций лямбды C++11)

Составлено свыпуском бьяма...для максимальной оптимизации/O2 /Ob2]profile_msvc_release

Составлено сотладкой бьяма...без оптимизации/Od/Ob0]profile_msvc_debug

GCC 4.3.4 СC++03Только (безC++11Функции лямбды и без «местных классов в качестве параметров шаблона»

Составлено срелизом бьяма...для максимальной оптимизации-O3 -finline-функции]profile_gcc_release

Составлено сотладкой бьяма...без оптимизации-O0 -fno-inline]profile_gcc_debug


PrevUpHomeNext

Статья Annex: Alternatives раздела Chapter 1. Boost.LocalFunction 1.0.0 Chapter 1. Boost.LocalFunction 1.0.0 может быть полезна для разработчиков на c++ и boost.




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.



:: Главная :: Chapter 1. Boost.LocalFunction 1.0.0 ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-30 11:47:00
2025-05-20 02:54:23/0.012218952178955/1