powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Опять завалил собеседование
55 сообщений из 55, показаны все 3 страниц
Опять завалил собеседование
    #38544656
cucaracha2014
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Специализируюсь на разработке архитектуры, ООП, юзаю Qt.

Когда прихожу на собеседование на вакансию с++, по части ООП не спрашивают кроме того баянистого примера с переменной массива в классе и отсутствием конструктором копирования. На ООП всем насррать.
Спрашивают про оптимизацию при работе с контейнерами STL.
1)Какую книгу прочитать, где достаточно полно описаны аспекты оптимизации при работе с STL?
2)Не люблю возиться с оптимизацией. Может следует отказаться от карьеры разработчика с++?
...
Рейтинг: 0 / 0
Опять завалил собеседование
    #38544684
egorych
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cucaracha2014, начни с этого: эффективное использование stl
...
Рейтинг: 0 / 0
Опять завалил собеседование
    #38544718
cucaracha2014
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
egorych,

спасибо
...
Рейтинг: 0 / 0
Опять завалил собеседование
    #38544933
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1)Какую книгу прочитать, где достаточно полно описаны аспекты оптимизации при работе с STL?

меерс, effective stl

2)Не люблю возиться с оптимизацией. Может следует отказаться от карьеры разработчика

ну, в общем да.
...
Рейтинг: 0 / 0
Опять завалил собеседование
    #38545012
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добавлю, что я ТОЖЕ не люблю возиться с оптимизацией.
И не нужно этим вообще заниматься, нужно сразу пытаться писать код с оглядкой на производительность.
Только это не заключается в подсчёте IF-ов и WHILE-ов, а в знании стоимостей операций.
...
Рейтинг: 0 / 0
Опять завалил собеседование
    #38545018
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
egorychcucaracha2014, начни с этого: эффективное использование stl

Ну, собственно, этим можно и закончить, потому что чтение этой книги вполне достаточно для того, чтобы вправить мозги по этой теме раз и навсегда.
...
Рейтинг: 0 / 0
Опять завалил собеседование
    #38545472
cucaracha2014
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MasterZiv,

благодарю
...
Рейтинг: 0 / 0
Опять завалил собеседование
    #38545474
cucaracha2014
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MasterZivДобавлю, что я ТОЖЕ не люблю возиться с оптимизацией.
нужно сразу пытаться писать код с оглядкой на производительность.

а это не одно и то же?
...
Рейтинг: 0 / 0
Опять завалил собеседование
    #38545655
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cucaracha2014MasterZivДобавлю, что я ТОЖЕ не люблю возиться с оптимизацией.
нужно сразу пытаться писать код с оглядкой на производительность.

а это не одно и то же?
Нет. Одно дело синтетические тесты во время разработки, другое - тормоза у юзера в реале из-за непредвиденных объемов данных или непредвиденного способа использования ПО. Сразу все предвидеть невозможно.
...
Рейтинг: 0 / 0
Опять завалил собеседование
    #38545702
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,

Сразу всё можно предвидеть на 80%, а это уже неплохо.
...
Рейтинг: 0 / 0
Опять завалил собеседование
    #38545709
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivDima T,

Сразу всё можно предвидеть на 80%, а это уже неплохо.
Верно, я про оставшиеся 20%, их приходится переписывать. Хотя чем больше предвидишь, тем меньше потом переписывать.
...
Рейтинг: 0 / 0
Опять завалил собеседование
    #38545732
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А еще бывает что для оптимизации ты специально везде писал
Код: plaintext
1.
void fun(const std::string& arg);


а потом в 2011 году оказалось что
Код: plaintext
1.
void fun(std::string arg) 

все равно быстрее.
...
Рейтинг: 0 / 0
Опять завалил собеседование
    #38545845
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky,

да ладно, это мелочи...
однако ты бы поделился опытом, в отдельном топике...
...
Рейтинг: 0 / 0
Опять завалил собеседование
    #38546241
alex_k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyА еще бывает что для оптимизации ты специально везде писал
Код: plaintext
1.
void fun(const std::string& arg);


а потом в 2011 году оказалось что
Код: plaintext
1.
void fun(std::string arg) 

все равно быстрее.
почему?
...
Рейтинг: 0 / 0
Опять завалил собеседование
    #38546269
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivв отдельном топике.
лень :)

alex_kпочему?
Потому что, если нам надо сохранить строку, то имея const std::string& мы ее можем только скопировать, а имея std::string мы можем перенести ее содержимое без копирования.
Для строк это не сильно заметно, т.к. многие реализации строк имеют copy-on-write(COW).
А например с объектами, где нет COW, ускорение при отказе от конст. ссылок может быть в разы.
Но естественно, будет ли ускорение зависит от алгоритма. Во многих случаях конст. ссылки быстрее.
Но суть в том что эта зависимость неочевидна, т.к. опирается на многие факторы, такие как инлайн-функции, выведение типов, RVO, rvalue-ссылки, std::move.
Поэтому программист заменяя значения ссылками фактически гадает, а не оптимизирует. Хотя конечно в большинстве случаев угадывает :)

В качестве бонуса привожу код, в котором при замене типа аргумента с конст. ссылки на значение (в остальном код одинаковый), происходит ускорение с 3.6 сек до 2.18 сек, т.е. в 1.65 раз. (Linux x64, G++ 4.8.2, -O2)
(Расход памяти 1ГБ)

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
#include <iostream>
#include <vector>
#include <map>
#include <boost/date_time.hpp>

using namespace std;

typedef std::map<int, int> value_t;
std::vector<value_t> v;

void add1(const value_t& s)
{
    v.emplace_back(std::move(s));
}

void add2(value_t s)
{
    v.emplace_back(std::move(s));
}

value_t gen_value()
{
    value_t res;
    for(size_t i = 0; i < 200; ++i)
       res[i] = i;
    return res;
}


template <typename AddFn> void test(AddFn fn)
{
    const size_t N = 100000;
    v.clear();
    v.reserve(N);
    boost::posix_time::ptime t1 = boost::posix_time::microsec_clock::universal_time();
    for(size_t i = 0; i < N; ++i) {
        fn(gen_value());
    }
    boost::posix_time::ptime t2 = boost::posix_time::microsec_clock::universal_time();
    cout << (t2-t1) << endl;

}

int main()
{
    // warm up
    test(add1); 
    test(add2);
    // test
    test(add1);
    test(add2);
    return 0;
}
...
Рейтинг: 0 / 0
Опять завалил собеседование
    #38546406
Фотография OoCc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky,

Это камень в огород C++. Еще одна причина почему C++ неможет быть системным языком.
...
Рейтинг: 0 / 0
Опять завалил собеседование
    #38546435
chabapok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
c++ конечно сакс и маздай, но ничего лучше долгое время не было.

и все же:

авторПотому что, если нам надо сохранить строку, то имея const std::string& мы ее можем только скопировать, а имея std::string мы можем перенести ее содержимое без копирования.

Что значит "перенести(1) ее содержимое без копирования(2)" ведь (1) взаимоисключает 2.
Не пойму.
...
Рейтинг: 0 / 0
Опять завалил собеседование
    #38546450
alex_k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
chabapok,

теперь есть move constructor, и xvalue
и stl контейнеры, видать, все это хорошо кушают :)

но это частный случай, который не говорит против передачи параметров по ссылкам, а говорит в пользу более тщательного изучения нового стандарта :)
...
Рейтинг: 0 / 0
Опять завалил собеседование
    #38546454
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
OoCcЭто камень в огород C++. Еще одна причина почему C++ неможет быть системным языком
Это не является причиной почему C++ не может быть системным языком.
И С++ может быть системным языком. :)

chabapokЧто значит "перенести(1) ее содержимое без копирования(2)" ведь (1) взаимоисключает 2.
Не пойму.
Большинство реализаций больших объектов держат данные в куче, а в самом объекте хранят только указатель на данные.
Копирование - это создание второго экземпляра данных в куче с копированием всех данных.
Перемещение- это копирование только указателя, а в исходном объекте указатель очищается, так что только новый объект указывает на эти данные. Это операция намного быстрее чем копирование.
Так как перемещение меняет исходный объект, то оно не может быть применено к константным объектам или ссылкам на них.
...
Рейтинг: 0 / 0
Опять завалил собеседование
    #38546467
chabapok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Но ведь и до этих ваших std::move можно было просто скопировать указатель, без копирования кучи. Тот же std::string это делал совершенно спокойно.
...
Рейтинг: 0 / 0
Опять завалил собеседование
    #38546472
chabapok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И вообще у вас тест некорректен, т.к. непонятно что с чем вы сравниваете - у вас в первом и втором вариантах на выходе, если я правильно понял, получаются разные данные. Там где move данных - у вас исходный обьект разрушается, а во втором случае нет.

То есть вы сравниваете функционально разные процедуры. (если я правильно понял как оно работает)
...
Рейтинг: 0 / 0
Опять завалил собеседование
    #38546487
Вася Уткин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В идеале бы universal reference: template<typename T> void add1(T&& s);

Если уж C++11 (std::move, emplace_back(), ...), то и rvalue reference:
авторtime = 3.1 sec
time = 2.2 sec
time = 2.2 sec
time = 2.1 sec

Anatoly Moskovsky
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
#include <iostream>
#include <vector>
#include <map>
#include <boost/date_time.hpp>

using namespace std;

typedef std::map<int, int> value_t;
std::vector<value_t> v;

void add1(value_t&& s)
{
    v.emplace_back(std::move(s));
}

void add2(value_t s)
{
    v.emplace_back(std::move(s));
}

value_t gen_value()
{
    value_t res;
    for(size_t i = 0; i < 200; ++i)
       res[i] = i;
    return res;
}


template <typename AddFn> void test(AddFn fn)
{
    const size_t N = 100000;
    v.clear();
    v.reserve(N);
    boost::posix_time::ptime t1 = boost::posix_time::microsec_clock::universal_time();
    for(size_t i = 0; i < N; ++i) {
        fn(gen_value());
    }
    boost::posix_time::ptime t2 = boost::posix_time::microsec_clock::universal_time();
    cout << (t2-t1) << endl;

}

int main()
{
    // warm up
    test(add1); 
    test(add2);
    // test
    test(add1);
    test(add2);
    return 0;
}
...
Рейтинг: 0 / 0
Опять завалил собеседование
    #38546500
Вася Уткин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А если уж C++03, то для производительности по другому делается.
Через ссылку и своп - 240мс
Через ссылку и копирование - 450мс
Через передачу по значению с двойным копированием объекта - 640мс
Получается в любом случае через ссылку больше возможностей к оптимизации :)

авторtime = 0.35 sec
time = 0.43 sec
time = 0.64 sec

time = 0.24 sec
time = 0.45 sec
time = 0.63 sec

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
#include <iostream>
#include <vector>
#include <map>
#include <ctime>       // clock_t, clock, CLOCKS_PER_SEC


using namespace std;

typedef std::map<int, int> value_t;
std::vector<value_t> v;



void add1(value_t& s)
{
    v.push_back(value_t());
    v.rbegin()->swap(s);
}

void add2(value_t& s)
{
    v.push_back(s);
}

void add3(value_t s)
{
    v.push_back(s);
}

void gen_value(value_t &res)
{
//	res.clear();
    for(size_t i = 0; i < 200; ++i)
       res[i] = i;
}


template <typename AddFn> void test(AddFn fn)
{
    const size_t N = 10000;
    v.clear();
    v.reserve(N);
    clock_t start = clock();
    for(size_t i = 0; i < N; ++i) {
    	value_t res;
    	gen_value(res);
        fn(res);
    }
    clock_t end = clock();
	float time = (float)(end - start)/CLOCKS_PER_SEC;
	std::cout << "time = " << time << " sec" << std::endl;

}

int main()
{
    // warm up
    test(add1); 
    test(add2);
    test(add3);
    std::cout << std::endl;
    // test
    test(add1);
    test(add2);
    test(add3);
    return 0;
}
...
Рейтинг: 0 / 0
Опять завалил собеседование
    #38546511
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вася Уткин,

Я привел пример для const& - стандартной идиоме для передачи объектов в функции.
Просто & не годится для временных объектов.

chabapokИ вообще у вас тест некорректен, т.к. непонятно что с чем вы сравниваете - у вас в первом и втором вариантах на выходе, если я правильно понял, получаются разные данные. Там где move данных - у вас исходный обьект разрушается, а во втором случае нет
В моем тесте исходный объект (gen_value()) разрушается в обоих случаях. Но со ссылкой это происходит медленнее.
...
Рейтинг: 0 / 0
Опять завалил собеседование
    #38546512
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyПросто & не годится для временных объектов.
А && не годится для невременных.
...
Рейтинг: 0 / 0
Опять завалил собеседование
    #38546515
Вася Уткин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly MoskovskyВася Уткин,

Я привел пример для const& - стандартной идиоме для передачи объектов в функции.
Просто & не годится для временных объектов.
Значит стандартная идиома передачи (временных) объектов в функции - не правильная :)
...
Рейтинг: 0 / 0
Опять завалил собеседование
    #38546541
Вася Уткин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly MoskovskyAnatoly MoskovskyПросто & не годится для временных объектов.
А && не годится для невременных.
&& годится, главное варить правильно :)
Вася УткинВ идеале бы universal reference: template<typename T> void add1(T&& s);

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
#include <iostream>
#include <vector>
#include <map>
#include <ctime>       // clock_t, clock, CLOCKS_PER_SEC


using namespace std;

typedef std::map<int, int> value_t;
std::vector<value_t> v;

template<typename T>
void add1(T&& s)
{
    v.emplace_back(std::move(s));
}

int main() {
	value_t tmp;
	add1(tmp);

	add1(value_t());

    return 0;
}
...
Рейтинг: 0 / 0
Опять завалил собеседование
    #38546719
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вася Уткин,

У шаблонов тоже есть ограничения, как например необходимость при инстанцировании иметь тела функций в той же единице трансляции. Это не всегда желательно.
...
Рейтинг: 0 / 0
Опять завалил собеседование
    #38546722
Вася Уткин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly MoskovskyВася Уткин,

У шаблонов тоже есть ограничения, как например необходимость при инстанцировании иметь тела функций в той же единице трансляции. Это не всегда желательно.
Это да. Хотя я честно не совсем понимаю, почему вариант void add2(value_t s); быстрее, ведь если add2() и gen_value() не inline функции, то почему отсутствует промежуточный этап копирования объекта из gen_value() в add2()?
...
Рейтинг: 0 / 0
Опять завалил собеседование
    #38546782
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вася УткинХотя я честно не совсем понимаю, почему вариант void add2(value_t s); быстрее, ведь если add2() и gen_value() не inline функции, то почему отсутствует промежуточный этап копирования объекта из gen_value() в add2()?
А почему вы думаете что они не inline? Из-за отсутствия ключевого слова inline? Так это уже давно не останавливает компиляторы (так же как и наличие inline не гарантирует ничего).
Даже передача указателя на функцию аргументом ничего не гарантирует :)

Впрочем в данном конкретном случае инлайнинга действительно скорее всего нет, а просто компилятор достаточно умен, чтобы передавать значения по указателю, а не копировать его.
Это например внутри может выглядеть так (опуская детали)
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
void gen_value(value_t* retval) 
{
    new (retval) value_t();  // RVO
    ...
}

void add2(value_t* s_ptr)
{
    value_t&& s = *s_ptr; // компилятор точно знает что передан указатель на rvalue. 
    ...
}

void test()
{
    value_t temp;
    gen_value(&temp); 
    add2(&temp);
}



Данная оптимизация передачи значения не зависит от наличия RVO или поддержки && (я их просто для полноты примера привел). Просто передаваемые параметры сохраняются в локальные переменные (или уже ими являются для очень многих случаев, как например в примере выше), и передается только адрес такой переменной. После выхода из функции значение такой переменной теряется.

ЗЫ. На всякий случай еще раз говорю - это псевдокод, и причем один из многих возможных. Реальный код может быть другим.
...
Рейтинг: 0 / 0
Опять завалил собеседование
    #38547140
Вася Уткин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly Moskovsky , ясно, просто тогда гарантировано ли будет происходить эта оптимизация если gen_value() и add2() будут в разных единицах трансляции? Сможет ли компилятор соптимизировать на уровне линковщика?
...
Рейтинг: 0 / 0
Опять завалил собеседование
    #38547304
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вася Уткинясно, просто тогда гарантировано ли будет происходить эта оптимизация если gen_value() и add2() будут в разных единицах трансляции? Сможет ли компилятор соптимизировать на уровне линковщика?
Способ передачи параметров by-value - это часть ABI компилятора, так что это не должно зависить от того в каком модуле определения функций.
...
Рейтинг: 0 / 0
Опять завалил собеседование
    #38547434
cucaracha2014
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly MoskovskyА еще бывает что для оптимизации ты специально везде писал
Код: plaintext
1.
void fun(const std::string& arg);


а потом в 2011 году оказалось что
Код: plaintext
1.
void fun(std::string arg) 

все равно быстрее.
что за ересь вы тут написали? не может быть такого!
...
Рейтинг: 0 / 0
Опять завалил собеседование
    #38547457
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cucaracha2014что за ересь вы тут написали? не может быть такого!
Вы наверно не читатель, а писатель. Иначе вы бы увидели, что я еще и код привел в качестве доказательства :)
...
Рейтинг: 0 / 0
Опять завалил собеседование
    #38547460
cucaracha2014
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly MoskovskyMasterZivв отдельном топике.
лень :)

alex_kпочему?
Потому что, если нам надо сохранить строку, то имея const std::string& мы ее можем только скопировать, а имея std::string мы можем перенести ее содержимое без копирования.
Для строк это не сильно заметно, т.к. многие реализации строк имеют copy-on-write(COW).
А например с объектами, где нет COW, ускорение при отказе от конст. ссылок может быть в разы.
Но естественно, будет ли ускорение зависит от алгоритма. Во многих случаях конст. ссылки быстрее.
Но суть в том что эта зависимость неочевидна, т.к. опирается на многие факторы, такие как инлайн-функции, выведение типов, RVO, rvalue-ссылки, std::move.

жжоте, однако :)
всё гораздо проще: есть встроенные типы (int,char,...) которые компилятор умеет оптимизировать(быстрое копирование) и есть все остальные
...
Рейтинг: 0 / 0
Опять завалил собеседование
    #38547467
cucaracha2014
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly Moskovskycucaracha2014что за ересь вы тут написали? не может быть такого!
Вы наверно не читатель, а писатель. Иначе вы бы увидели, что я еще и код привел в качестве доказательства :)
в случае со stringом ваш тест опровергнет ваше утверждение
...
Рейтинг: 0 / 0
Опять завалил собеседование
    #38547483
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cucaracha2014,

Идите дальше читайте книгу про оптимизацию.
У вас пока не получается :)
...
Рейтинг: 0 / 0
Опять завалил собеседование
    #38547495
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да, забыл написать
Для std::string результаты такие:
00:00:01.786493
00:00:01.544935
00:00:01.732854
00:00:01.542740

Не в полтора раза конечно, но достаточно чтобы cucaracha2014 опять не прошел собеседование
...
Рейтинг: 0 / 0
Опять завалил собеседование
    #38547513
cucaracha2014
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly MoskovskyДа, забыл написать
Для std::string результаты такие:
00:00:01.786493
00:00:01.544935
00:00:01.732854
00:00:01.542740

Не в полтора раза конечно, но достаточно чтобы cucaracha2014 опять не прошел собеседование
что это за магичесие числа?
выкладывайте код
...
Рейтинг: 0 / 0
Опять завалил собеседование
    #38547551
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cucaracha2014,

Я так понимаю, что специалистам по разработке архитектуры и ООП не положено знать как заменить один typedef и получить код для нового типа. :)

Держите.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <boost/date_time.hpp>

using namespace std;

//typedef std::map<int, int> value_t;
typedef std::string value_t;
std::vector<value_t> v;

void add1(const value_t& s)
{
    v.emplace_back(std::move(s));
}

void add2(value_t s)
{
    v.emplace_back(std::move(s));
}

//value_t gen_value()
//{
//    value_t res;
//    for(size_t i = 0; i < 20; ++i)
//       res[i] = i;
//    return res;
//}

value_t gen_value()
{
    value_t res(2000, '*');
    return res;
}


template <typename AddFn> void test(AddFn fn)
{
    const size_t N = 10000000;
    v.clear();
    boost::posix_time::ptime t1 = boost::posix_time::microsec_clock::universal_time();
    for(size_t i = 0; i < N; ++i) {
        fn(gen_value());
        v.clear(); // consume generated value
    }
    boost::posix_time::ptime t2 = boost::posix_time::microsec_clock::universal_time();
    cout << (t2-t1) << endl;

}

int main()
{
    test(add1);
    test(add2);
    test(add1);
    test(add2);
    return 0;
}



ЗЫ. Подправил код, чтобы не было расхода памяти при большом числе итераций.
...
Рейтинг: 0 / 0
Опять завалил собеседование
    #38547604
cucaracha2014
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly Moskovsky,

для чистоты эксперимента уберите std::move и результаты в студию!
...
Рейтинг: 0 / 0
Опять завалил собеседование
    #38547627
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cucaracha2014для чистоты эксперимента уберите std::move и результаты в студию!
С какой стати?
Для чистоты эксперимента достаточно чтобы прототипы функций совпалали с тем что я утверждал.
Код: plaintext
1.
2.
void fun(const std::string& arg);
void fun(std::string arg);


А про тела функций я никаких утверждений, требующих доказательств не приводил.
...
Рейтинг: 0 / 0
Опять завалил собеседование
    #38547753
BagaBaga
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky,
этот "прикол" работает только потому,

что в новом стандарте появились movable types и movable constructors (etc...)
что STL переработана с учётом movable-семантики
что в вашем тесте используется вызов fn(gen_value()), т.е. есть неявная временная переменная

В результате в fn(gen_value()) вызов gen_value() возвращает неименованную временную переменную, которая принимается movable-конструктором контейнера. Далее, за счёт инструкции std::move этот элемент "воруется" в новый контейнер. При этом std::move - это просто приведение типа, не более того (подробнее - http://www.aristeia.com/videos/Gn13ScottMeyersAnEffectiveCPP_high.mp4 ). Само оно ничего не перемещает. В случае с передачей по константной ссылке "своровать" вы явно запрещаете модификатором const - константность означает неизменяемость объекта, а вы его меняете. Почему не происходит ошибки при попытке применить move к const-объекту? Это вопрос к стандарту. В приведении типов const побеждает.

И, да. Появление "перемещаемых" объектов - это появление новой парадигмы, которая существенно меняет стилистику написания кода.
...
Рейтинг: 0 / 0
Опять завалил собеседование
    #38547790
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BagaBagaэтот "прикол" работает только потому,

что в новом стандарте появились movable types и movable constructors (etc...)
что STL переработана с учётом movable-семантики
Я вообще-то изначально так и сказал, что это появилось в С++ в 11 году.

BagaBagaПри этом std::move - это просто приведение типа, не более того ...Само оно ничего не перемещает
Это да.
BagaBagaВ случае с передачей по константной ссылке "своровать" вы явно запрещаете модификатором const - константность означает неизменяемость объекта, а вы его меняете
А тут непонятно, почему вы решили что move изменяет объект, если вы только что выше написали что он ничего не меняет? :)

Рекомендую в таких случаях читать доку и узнавать что на самом деле должно происходить.
В частности, для константных объектов move возвращает const&& а для неконстантных - &&.
Первый вариант передается в конструктор копирования (поскольку обычно отсутствует отдельный конструктор для const&&), а второй - в конструктор перемещения.
Вот и все дела.
...
Рейтинг: 0 / 0
Опять завалил собеседование
    #38547796
avlaxoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivДобавлю, что я ТОЖЕ не люблю возиться с оптимизацией.
И не нужно этим вообще заниматься, нужно сразу пытаться писать код с оглядкой на производительность.
Только это не заключается в подсчёте IF-ов и WHILE-ов, а в знании стоимостей операций.

+10.
...
Рейтинг: 0 / 0
Опять завалил собеседование
    #38547830
BagaBaga
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyBagaBagaВ случае с передачей по константной ссылке "своровать" вы явно запрещаете модификатором const - константность означает неизменяемость объекта, а вы его меняете
А тут непонятно, почему вы решили что move изменяет объект, если вы только что выше написали что он ничего не меняет? :)

Рекомендую в таких случаях читать доку...

Хм. move - подсказка компилятору, не более того (т.к. просто приведение типа). Теперь "про меняет - не меняет".

vector<int> a(10,1);
vector<int> b;
b = move(a);

Что мы здесь имеем? Мы изменяем вектор a. Как? Мы "воруем" у него элементы для вектора b (точнее, мы даём подсказку компилятору, что - если возможно, - нужно "своровать содержимое" вектора a для вектора b). Что будет храниться в векторе a, после того как из него "утянули содержимое" в вектор b? Стандарт говорит, что объект, "у которого украли", может былить в unspecified состоянии, а его дальнейшее использование может приводить к undefined behavior. Но это в общем случае. Для вектора гарантируется, что объект будет находится в консистентном состоянии (нулевой вектор, и использовать его можно). Не помню, есть ли такая гарантия для string.

Итого - move "сам по себе" ничего не меняет, т.к. является просто приведением типа. Использование move семантически несёт в себе "смысл" изменения исходного объекта путем "переноса" данных в приёмник. Правда, в ряде случаев (например, источника с квалификатором const), это "технически" реализуется посредством копирования...

А стандарт... да, нужно читать.
...
Рейтинг: 0 / 0
Опять завалил собеседование
    #38547958
chabapok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вот так обьявлен мов:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
template< class T >
typename std::remove_reference<T>::type&& move( T&& t );

//а вот так ремов референц
template< class T > struct remove_reference      {typedef T type;};
template< class T > struct remove_reference<T&>  {typedef T type;};
template< class T > struct remove_reference<T&&> {typedef T type;};



Не очень понимаю как можно сделать typename для функции. Кто-нибудь може мне обьяснить? Это просто приведение к T&& что ли?

Мне кажется, что это просто приводят обьект к lvalue
То есть фактически, начего нового не происходит, и вся эта с++11 и прирост производительности основан на магии внутри vector, которую можно было бы спокойно сделать и без с++11, невыдумывая это все.

или я не понимаю чего-то.
...
Рейтинг: 0 / 0
Опять завалил собеседование
    #38547964
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
chabapoktemplate< class T >
typename std::remove_reference<T>::type&& move( T&& t );

Не очень понимаю как можно сделать typename для функции. Кто-нибудь може мне обьяснить?


typename -- ключевое слово, которое говорит компилятору, что далее по тексту, следующей лексемой идёт тип данных, а не
что-то другое.

Функция с типом возврата и сигнатурой параметра является в С++ (и С) типом данных, таким же (почти) как и другие типы.
Функция как тип данных может определять только один производный тип -- это указатель на такую функцию.
Собственно, тип функции и тип указателя на функцию -- это одно и то же.

Собственно, не понятно, в чём проблема ввести тип фукнции через typename.

Ну и тут typename относится не к функции, а к "std::remove_reference<T>::type&& " , и говорит, что это -- тип данных,
а не ещё какой-то элемент языка.
Всё вместе объявляет прототип функции `move' c параметром T&& t , которая возвращает std::remove_reference<T>::type&&
...
Рейтинг: 0 / 0
Опять завалил собеседование
    #38547979
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
chabapokМне кажется, что это просто приводят обьект к lvalue
Вот я не понимаю, зачем гадать, когда можно просто прочитать в доке по move () в два клика?
В С++11 то, что возвращает move, называется xvalue (expiring value) - значение, дальнейшая судьба которого программиста уже не интересует.
Кстати в большинстве случаев явный move() не нужен, т.к. компилятор сам способен понять, что если переменная например выходит из области видимости, то ей можно автоматически делать move.
chabapokТо есть фактически, начего нового не происходит, и вся эта с++11 и прирост производительности основан на магии внутри vector, которую можно было бы спокойно сделать и без с++11, невыдумывая это все.
Нет, хоть это частично и было возможно через явное использование swap (см. выше код Уткина для С++03), но во-первых это приводило к громоздкому и малопонятному коду, и что важнее, например перемещающие конструкторы или присвоения не были возможны, т.к. программист имея константную ссылку как параметр не мог гарантировать, что там временная переменная, а не просто константный алиас на объект, который еще понадобится.
Только в С++11 появились ссылки &&, которые соответствуют именно временным (и вообще любым xvalue) объектам и позволяют создавать отдельные перегрузки.
И переделанный с учетом этого STL, автоматически ускорил (не везде конечно) существующий С++03 код, который про && и move вообще не в курсе.
chabapokили я не понимаю чего-то.
Да. Или.
...
Рейтинг: 0 / 0
Опять завалил собеседование
    #38548332
cucaracha2014
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly Moskovskycucaracha2014для чистоты эксперимента уберите std::move и результаты в студию!
С какой стати?
Для чистоты эксперимента достаточно чтобы прототипы функций совпалали с тем что я утверждал.
Код: plaintext
1.
2.
void fun(const std::string& arg);
void fun(std::string arg);


А про тела функций я никаких утверждений, требующих доказательств не приводил.
Подразумевалось, что тела функций - одинаковые. Иначе какой смысл замерять время выполнения?
Тот факт, что в вашем примере выглядят одинаково при различной работе - это скорее исключение, чем правило, причём это только благодаря извращениям в новом стандарте, который почти никто до сих пор не использует(и правильно).
...
Рейтинг: 0 / 0
Опять завалил собеседование
    #38548869
Вася Уткин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly MoskovskyИ переделанный с учетом этого STL, автоматически ускорил (не везде конечно) существующий С++03 код, который про && и move вообще не в курсе.
А можете привести такой пример?
Потому как в примере выше, переделанный с учетом этого STL, все таки не ускорял автоматически существующий C++03 код, т.к. было добавлено emplace_back() и move(), что уже не C++03 код :)
...
Рейтинг: 0 / 0
Опять завалил собеседование
    #38549051
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вася УткинА можете привести такой пример?
Потому как в примере выше, переделанный с учетом этого STL, все таки не ускорял автоматически существующий C++03 код, т.к. было добавлено emplace_back() и move(), что уже не C++03 код :)
Могу, че ж не привести.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
void add_noopt()
{
    value_t temp(gen_value());
    v.push_back(temp);
}

void add_opt()
{
    v.push_back(gen_value());
}

template <typename AddFn> void test2(AddFn fn)
{
    const size_t N = 1000000;
    v.clear();
    boost::posix_time::ptime t1 = boost::posix_time::microsec_clock::universal_time();
    for(size_t i = 0; i < N; ++i) {
        fn();
        v.clear(); // consume generated value
    }
    boost::posix_time::ptime t2 = boost::posix_time::microsec_clock::universal_time();
    cout << (t2-t1) << endl;

}

int main()
{
    test2(add_noopt);
    test2(add_opt);
    test2(add_noopt);
    test2(add_opt);

    return 0;
}



Если откомпилировать в режиме С++03 то получим такие цифры
00:00:03.441272
00:00:03.446451
00:00:03.444534
00:00:03.463694

В режиме С++11
00:00:03.437164
00:00:02.194824
00:00:03.394935
00:00:02.191499

По моему функция add_opt очень так неплохо соптимизировалась в 1.57 раза.
Предоставляю Кукараче2014 возможность разобраться почему add_noopt не соптимизировалась
...
Рейтинг: 0 / 0
Опять завалил собеседование
    #38549131
cucaracha2014
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly MoskovskyПредоставляю Кукараче2014 возможность разобраться почему add_noopt не соптимизировалась
это очень интересно: почему с использованной временной переменной код получился быстрее более чем в 2 раза
я думаю что это нужно спрашивать у разраюотчиков
...
Рейтинг: 0 / 0
Опять завалил собеседование
    #38549140
cucaracha2014
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
cucaracha2014Anatoly MoskovskyПредоставляю Кукараче2014 возможность разобраться почему add_noopt не соптимизировалась
это очень интересно: почему с использованной временной переменной код получился быстрее более чем в 2 раза
я думаю что это нужно спрашивать у разработчиков
это уже за гранью добра и зла
...
Рейтинг: 0 / 0
Опять завалил собеседование
    #38549449
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cucaracha2014я думаю что это нужно спрашивать у разраюотчиков
Либо авторследует отказаться от карьеры разработчика с++
...
Рейтинг: 0 / 0
55 сообщений из 55, показаны все 3 страниц
Форумы / C++ [игнор отключен] [закрыт для гостей] / Опять завалил собеседование
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]