Считается ли
git add -A && git commit -m "Your Message"
«единой командой»?
Редактировать на основании ответа @ thefinnomenon ниже :
Чтобы получить его как git alias
, используйте:
git config --global alias.coa '!git add -A && git commit -m'
и зафиксируйте все файлы, включая новые, с сообщением:
git coa "A bunch of horrible changes"
Объяснение (из git add
документации ):
-A, --all, --no-ignore-removal
Обновлять индекс не только там, где В рабочем дереве есть соответствие файла, но также там, где в индексе уже есть запись. Это добавляет, изменяет и удаляет записи индекса, чтобы соответствовать рабочему дереву.
Если не задано
при использовании опции -A, обновляются все файлы во всем рабочем дереве (старые версии Git использовались для ограничения обновления текущим каталогом и его подкаталогами).
Пример (b) имеет другое значение, чем пример (a), и компилятор должен интерпретировать его, когда вы его пишете.
Если, (по какой-то надуманной причине, что я могу не думаю), я написал код для этого:
for( int i(0);i < vec.length(); ++i)
{
if(i%4 == 0)
vec.push_back(Widget());
}
Я действительно не хотел бы, чтобы компилятор оптимизировал каждый вызов vec.length (), потому что я бы получил разные результаты.
Почему это вам суждено? Эти две альтернативы не делают того же самого. Один выполняет фиксированное количество итераций, а другой зависит от тела цикла.
Другой альтернативный вариант:
for (vector<T>::iterator it=vec.begin();it!=vec.end();it++){
//loop body
}
Если вам не нужна переменная цикла вне цикла, второй подход предпочтительнее.
Итераторы фактически дадут вам такую же или лучшую производительность. (Несколько лет назад был большой поток сравнений на comp.lang.c ++., Модерированный.)
Кроме того, я бы использовал
int i = 0;
, а не конструктор, подобный синтаксису, который вы используете. Хотя это действительно так, это не идиоматика.
Мне нравится:
for (int i = 0, e = vec.length(); i != e; ++i)
Конечно, это также будет работать для итераторов:
for (vector<int>::const_iterator i = v.begin(), e = v.end(); i != e; ++i)
Мне это нравится, потому что это одновременно эффективно (вызов end ()
только один раз) , а также относительно лаконично (достаточно ввести vector
один раз).
Здесь необходимо обсудить два вопроса:
Обычно вам не нужно, чтобы переменная цикла была видна за пределами петля. Вот почему вы можете объявить его внутри конструкции for
.
Эндрю Шеперд красиво сформулировал это: это означает нечто иное, чтобы поместить вызов функции внутри конечного условия:
for( vector<...>::size_type i = 0; i < v.size(); ++i ) { // vector size may grow.
if( ... ) v.push_back( i ); // contrived, but possible
}
// note: this code may be replaced by a std::for_each construct, the previous can't.
for( vector<...>::size_type i = 0, elements = v.size(); i != elements; ++i ) {
}
Скорее не связано:
Предупреждение: сравнение знаковых и беззнаковых целых чисел.
Правильный тип для массивов и векторных индексов - size_t .
Строго говоря, в C ++ это даже std :: vector <> :: size_type
.
Удивительно, сколько разработчиков C / C ++ все еще ошибаются.
Компилятору очень сложно поднять вызов vec.length ()
, зная, что он постоянный, если только он не будет встроен (что, надеюсь, часто будет! ). Но по крайней мере i
определенно следует объявить во втором стиле «b», даже если вызов length
необходимо «вручную» вывести из цикла!
Предпочтительнее этот:
typedef vector<int> container; // not really required,
// you could just use vector<int> in for loop
for (container::const_iterator i = v.begin(); i != v.end(); ++i)
{
// do something with (*i)
}
v.end ()
возвращает указатель один за
последний элемент, поэтому нет накладных расходов
размер проверки Следует отметить, что примеры итераторов:
for (vector<T>::iterator it=vec.begin();it!=vec.end();it++){
//loop body
}
могут сделать недействительным итератор цикла «it», если тело цикла вызовет перераспределение вектора. Таким образом, это не эквивалентно
for (int i=0;i<vec.size();++i){
//loop body
}
, где тело цикла добавляет элементы к vec.
Простой вопрос: изменяете ли вы vec
в цикле?
ответ на этот вопрос также приведет к вашему ответу.
jrh
Я удивлен, что никто не сказал очевидного:
В 99,99% случаев это не имеет значения.
Если только вы не используете какой-то контейнер, в котором вычисляется размер ()
- дорогостоящая операция, непостижимо, что ваша программа будет работать даже на несколько наносекунд медленнее. Я бы посоветовал придерживаться более удобочитаемого кода, пока вы не профилируете свой код и не обнаружите, что size ()
является узким местом.
Почему бы не обойти эту проблему полностью с помощью BOOST_FOREACH
#include <boost/foreach.hpp>
std::vector<double> vec;
//...
BOOST_FOREACH( double &d, vec)
{
std::cout << d;
}
Посмотрим на сгенерированный код (я использую MSVS 2008 с полной оптимизацией).
a.
int i(0), iMax(vec.size());//vec is a container, say std::vector
for(;i < iMax; ++i)
{
//loop body
}
Цикл for производит 2 инструкции ассемблера.
b.
for( int i(0);i < vec.size(); ++i)
{
//loop body
}
Цикл for производит 8 инструкций ассемблера. vec.size () успешно встроен.
c.
for (std::vector<int>::const_iterator i = vec.begin(), e = vec.end(); i != e; ++i)
{
//loop body
}
Цикл for создает 15 инструкций ассемблера (все встроено, но в коде много переходов)
Итак, если ваше приложение критично по производительности, используйте а). В противном случае b) или c).
(b) won't calculate/call the function each time.
-- begin excerpt ----
Loop Invariant Code Motion: GCC включает инвариантное движение кода цикла как часть своего оптимизатора цикла, а также в проход устранения частичной избыточности. Эта оптимизация удаляет инструкции из циклов, которые вычисляют значение, которое не изменяется в течение всего времени существования цикла.
--- конец отрывка -
Дополнительные оптимизации для gcc:
https://www.in .redhat.com / software / gnupro / Technical / gnupro_gcc.php3