Функция:
public float simpleSimilarity(String u, String v) {
String[] a = u.split(" ");
String[] b = v.split(" ");
long correct = 0;
int minLen = Math.min(a.length, b.length);
for (int i = 0; i < minLen; i++) {
String aa = a[i];
String bb = b[i];
int minWordLength = Math.min(aa.length(), bb.length());
for (int j = 0; j < minWordLength; j++) {
if (aa.charAt(j) == bb.charAt(j)) {
correct++;
}
}
}
return (float) (((double) correct) / Math.max(u.length(), v.length()));
}
Тест:
String a = "This is the first string.";
String b = "this is not 1st string!";
// for exact string comparison, use .equals
boolean exact = a.equals(b);
// For similarity check, there are libraries for this
// Here I'll try a simple example I wrote
float similarity = simple_similarity(a,b);
О, человек, один из моих питомцев.
inline
больше похож на static
или extern
, чем на директиву, сообщающую компилятору встроить ваши функции. extern
, static
, inline
являются директивами привязки, которые используются почти исключительно компоновщиком, а не компилятором.
Говорят, что inline
намекает компилятору, что, по вашему мнению, функция должна быть встроенным. Это могло быть правдой в 1998 году, но десятилетие спустя компилятор не нуждается в таких подсказках. Не говоря уже о том, что люди обычно ошибаются, когда дело доходит до оптимизации кода, поэтому большинство компиляторов полностью игнорируют «подсказку».
static
- имя переменной / функции не может использоваться в другом переводе единицы. Linker должен убедиться, что он случайно не использует статически определенную переменную / функцию из другой единицы перевода. extern
- используйте это имя переменной / функции в этой единицы перевода, но не жалуйтесь, если это не определено. Компилятор будет сортировать его и убедиться, что весь код, который пытался использовать какой-либо символ extern, имеет свой адрес. inline
- эта функция будет определена в нескольких единицах перевода, не беспокойтесь об этом , Компилятор должен убедиться, что все единицы перевода используют один экземпляр переменной / функции. Примечание. Как правило, объявление шаблонов inline
бессмысленно, так как они имеют семантику связи inline
уже. Тем не менее, специализация explicit
и создание экземпляров шаблонов требуют использования inline
.
Конкретные ответы на ваши вопросы:
private
встроены независимо от того, запрашиваете вы это или нет. Для предотвращения встраивания в GCC используйте __attribute__(( noinline ))
, а в Visual Studio используйте __declspec(noinline)
. 1) В наше время почти никогда. Если это хорошая идея, чтобы встроить функцию, компилятор сделает это без вашей помощи.
2) Всегда. См. № 1.
(Отредактировано с учетом того, что вы нарушили свой вопрос на два вопроса ...)
inline
по-прежнему необходимо, например, чтобы определить i> функцию в файле заголовка (и это необходимо для встраивания такой функции в несколько единиц компиляции).
– Melebius
18 November 2014 в 12:25
inline
, его экземпляры автоматически сжимаются в один компоновщиком, а ODR не используется.
– Ruslan
22 November 2016 в 15:11
Когда нужно встроить:
1. Когда кто-то хочет избежать накладных расходов на вещи, возникающие при вызове функции как передача параметров, передача управления, возврат управления и т. д.
2. Функция должна быть небольшой, часто вызываемой и сделать встроенную, действительно выгодной, поскольку в соответствии с правилом 80-20 попытайтесь сделать эту функцию встроенной, что оказывает значительное влияние на производительность программы.
Как известно, inline - это просто запрос к компилятору, подобный регистру, и он будет стоить вам при размере кода объекта.
inline
потерял свой статус подсказки оптимизации, и большинство компиляторов используют его только для того, чтобы сделать допущения для нескольких определений - как ИМО, которым они должны. Более того, поскольку C ++ 11, register
полностью устарел из-за своего прежнего значения «Я знаю лучше, чем компилятор, как оптимизировать»: теперь это просто зарезервированное слово без текущего значения.
– underscore_d
4 October 2016 в 20:20
Вам все равно нужно явно встраивать свою функцию при выполнении специализированной специализации (если специализация находится в файле .h)
Если вы не пишете библиотеку или не имеете особых причин, вы можете забыть о inline
и использовать оптимизацию времени ссылки . Он устраняет требование определения определения функции в заголовке, чтобы оно учитывалось для вложения между единицами компиляции, что и позволяет inline
.
(Но см. Есть ли какая-либо причина почему бы не использовать оптимизацию времени ссылки? )
В действительности, почти никогда. Все, что вы делаете, означает, что компилятор делает заданную функцию встроенной (например, заменяет все вызовы на эту функцию / w ее тело). Конечно, нет никаких гарантий: компилятор может игнорировать директиву.
Компилятор обычно хорошо справляется с обнаружением + оптимизации таких вещей.
inline
имеет разницу семантической i> в C ++ (например, в способе обработки нескольких определений), что важно в некоторых случаях (например, шаблоны).
– Pavel Minaev
18 November 2009 в 23:55
Я хотел бы внести свой вклад во все замечательные ответы в этом потоке с убедительным примером, чтобы разогнать все оставшиеся недоразумения.
Для двух исходных файлов, таких как:
#include <iostream>
void bar();
inline int fun() {
return 111;
}
int main() {
std::cout << "inline111: fun() = " << fun() << ", &fun = " << (void*) &fun;
bar();
}
#include <iostream>
inline int fun() {
return 222;
}
void bar() {
std::cout << "inline222: fun() = " << fun() << ", &fun = " << (void*) &fun;
}
g++ -std=c++11 inline111.cpp inline222.cpp
Выход : inline111: fun() = 111, &fun = 0x4029a0
inline222: fun() = 111, &fun = 0x4029a0
Обсуждение : Даже у вас должно быть одинаковое определение ваших встроенных функций, компилятор C ++ не указывает его, если это не (на самом деле, из-за отдельной компиляции у него нет способов проверить это). Это ваша обязанность обеспечить это! Linker не жалуется на Одно правило определения , поскольку fun()
объявлено как inline
. Однако, поскольку inline111.cpp является первой единицей перевода (которая на самом деле вызывает fun()
), обработанной компилятором, компилятор создает экземпляр fun()
на его первом вызове-вызове inline111.cpp. Если компилятор решает не расширять fun()
по его вызову из любого места в вашей программе (, например из inline222.cpp), вызов fun()
всегда будет связан с его экземпляром, созданным из inline111. cpp (вызов fun()
внутри inline222.cpp также может привести экземпляр в этой единицы перевода, но он останется несвязанным). Действительно, это видно из идентичных распечаток &fun = 0x4029a0
. Наконец, несмотря на предложение inline
компилятору на самом деле расширить однострочный fun()
, он полностью игнорирует ваше предложение, что ясно, потому что fun() = 111
в обе линии. g++ -std=c++11 inline222.cpp inline111.cpp
Выход : inline111: fun() = 222, &fun = 0x402980
inline222: fun() = 222, &fun = 0x402980
Обсуждение : этот случай утверждает то, что обсуждалось в случае А. Обратите внимание на важный момент, что если вы закомментируете фактический вызов fun()
inline222.cpp ( ] например, полностью закомментировать cout
-statement inline222.cpp), то, несмотря на порядок компиляции ваших единиц перевода, fun()
будет создан при первом вызове вызова inline111.cpp, для случая B как inline111: fun() = 111, &fun = 0x402980
. g++ -std=c++11 -O2 inline222.cpp inline111.cpp
или g++ -std=c++11 -O2 inline111.cpp inline222.cpp
Выход : inline111: fun() = 111, &fun = 0x402900
inline222: fun() = 222, &fun = 0x402900
Обсуждение : Как описано здесь , оптимизация -O2
побуждает компилятор к фактически расширять функции, которые (обратите внимание также, что -fno-inline
- по умолчанию без параметров оптимизации). Как видно из отпечатка здесь, fun()
фактически был встроенным расширенным (согласно его определению в этой особой блоке трансляции), в результате чего два разных fun()
распечатки. Несмотря на это, все еще существует только один глобально связанный экземпляр fun()
(как требуется стандартом), как видно из идентичного &fun
распечатки. inline
неопределенным.
– R Sahu
29 May 2018 в 15:50
gcc по умолчанию не строит никаких функций при компиляции без оптимизации. Я не знаю о visual studio - deft_code
blockquote>Я проверил это для Visual Studio 9 (15.00.30729.01), компилировав / FAcs и посмотрев на код сборки: компилятор произвел вызовы функции-члены без оптимизации включены в режиме отладки. Даже если функция отмечена __forceinline, не создается встроенный код времени выполнения.
Вы хотите поставить его в самом начале, перед типом возврата. Но большинство компиляторов игнорируют это. Если он определен и имеет меньший блок кода, большинство компиляторов все равно считают его inline.
Когда я не должен писать ключевое слово 'inline' для функции / метода в C ++?
blockquote>Если функция определена в файле
.cpp
, вы должны not записать ключевое слово.Когда компилятор не знает, когда нужно сделать функцию / метод 'inline'?
blockquote>Такой ситуации нет. Компилятор не может сделать функцию встроенной. Все, что он может сделать, это вставить некоторые или все вызовы функции. Он не может этого сделать, если у него нет кода функции (в этом случае компоновщик должен сделать это, если он в состоянии это сделать).
Имеет ли значение, если приложение многопоточно, когда вы пишете 'inline' для функции / метода?
blockquote>Нет, это вообще не имеет значения.
Это зависит от используемого компилятора. Не слепо доверяйте, что в наши дни компиляторы лучше знают людей, как внедряться, и вы никогда не должны использовать его по соображениям производительности, потому что это директива linkage, а не подсказка оптимизации. Хотя я согласен с тем, что идеологически эти аргументы правильной встречей с реальностью может быть другой.
После прочтения нескольких потоков вокруг я опробовал из любопытства эффекты встроенного кода, который я только что работал, и результаты были что я получил измеримое ускорение для GCC и не ускоряюсь для компилятора Intel.
(Подробнее: математическое моделирование с несколькими критическими функциями, определенными вне класса, GCC 4.6.3 (g ++ -O3), ICC 13.1.0 (icpc-O3), добавив inline к критическим точкам, вызвав + 6% ускорение с кодом GCC).
Итак, если вы квалифицируете GCC 4.6 как современный компилятор, результатом является то, что директива inline по-прежнему имеет значение, если вы пишете CPU интенсивные задачи и знать, где именно находится узкое место.
При разработке и отладке кода оставьте inline
. Это усложняет отладку.
Основная причина их добавления - помочь оптимизировать сгенерированный код. Обычно этот трейд увеличивает пространство кода для скорости, но иногда inline
сохраняет как пространство кода, так и время выполнения.
Рассекая эту мысль о оптимизации производительности до завершения алгоритма преждевременная оптимизация .
inline
функции, как правило, не встроены, если они не компилируются с оптимизацией, поэтому они никак не влияют на отладку. Помните, что это намек, а не требование.
– Pavel Minaev
18 November 2009 в 23:54
inline
были встроены. В них невозможно было установить в них осмысленную точку останова.
– wallyk
19 November 2009 в 00:19
inline
ничего не сделает для улучшения кода в современном компиляторе, который может выяснить, является ли встроенным или нет самостоятельно.
– David Thornley
20 November 2009 в 23:22
inline
не связаны. Однако у вас есть правильная идея. Как правило, угадать, что было бы улучшено путем inline, очень подвержено ошибкам. Исключение из этого правила - это один лайнер. – deft_code 15 August 2011 в 19:50