Программируем с GPT
Мне всё-таки кажется, что в интернете достаточно примеров как замечательно нейросети справляются с программированием, надо восстанавливать баланс. Свежий пример из моей практики.
Нужно было переписать вот такой код с «Пайтона» на «Си++»:
{72: 65, 80: 66}.get(value, 0)
Что тут происходит? Если value равно 72, вернуть 65, если 80, то 66, иначе ноль. Нужно мне это, если вкратце, для преобразования виндовых кодов в линуксовые.
Так как Си++ я не знаю, описал на Пайтоне — так быстрее и проще показать, что код мне нужен компактный — хочется не городить switch, а добавлять новое правило как можно проще.
Вот что мне сгенерировал ChatGPT-4:
int value = 72;
std::map<int, int> mymap = {{72, 65}, {80, 66}};
int result = mymap.count(value) ? mymap[value] : 0;
После консультации с живыми людьми, выяснилось, что плохо тут примерно всё.
Во-первых, вместо map надо использовать unordered_map, сложность поиска по первой структуре логарифмическая, по второй — константная в среднем.
Во-вторых, в этом коде надо использовать find, а не count, так как find остановится после первого совпадения (что нам и надо), а count — нет, продолжая тратить ресурсы.
В-третьих, map создаётся в этом примере каждый раз вместо одного. Хороший программист так это не оставит.
В итоге, код стал выглядеть следующим образом:
const static std::unordered_map<int, int> win2lin = {{72, 65}, {80, 66}};
auto it = win2lin.find(_getch());
ch = it == win2lin.end() ? 0 : it->second;
Для порядка отмечу, что поиск в map логарифмический по сложности, а в unordered_map константный в среднем, но линейный в худшем случае.
Спасибо, посмотрел чат, действительно, ребята писали про логарифмический (а про линейный в худшем не писали). Сейчас поправлю.
Не могу спокойно смотреть тут ни на map, ни unordered_map. Так-то оно, конечно, ближе по духу к Пайтону, но у мэпов очень большой константный множитель, из-за чего их эффективность выстрелит только на достаточно больших списках. Тут же и проще и быстрее использовать просто массив.
Вот, компилятор прекрасно справляется вообще убрать все циклы и заменить их просто на пару сравнений: https://godbolt.org/z/8sW8xc7e8
А вот как выглядит то же самое на unordered_map: https://godbolt.org/z/TWcq6ooeb
Но заставить Chat 3.5 написать вместо map что-то вменяемое никак не получилось... Какую-то жуть всё время предлагает.
Я совсем не против реквестов в репозиторий, тем более, как я говорил много раз ранее — я не знаю Си++, просто хотелось как-то дёшево записать, чтобы при нужде потом просто было пару чисел добавить )
P. S. Код исправил на ваш.
Не хватает контекста. Сейчас два значения, а сколько ожидается, 5, 15, 100? Кажется, от этого зависит, какой сложности огород городить. Для двух значений и if сгодился бы.
Пока порядка пяти, но в сущности я не знаю, не больше, чем кодов клавиатуры, это преобразование виндовых кодов в линуксовые.
Я не уверен, но вроде в Питоне тоже каждый раз словарь будет создаваться.
Это от оптимизаций зависит, разумеется, но без оптимизаций — конечно. Это же изменяемый тип, он не интернируется.
Но хороший программист на Си++ так это точно не оставит.
о май гад,больно смотреть:) если ты не написал иф для порядка пяти значений, а написал map или unordered_map, то у тебя больше нет права жаловаться на неэффективность:)
))) я понимаю, что map/unordered_map тут из пушки по воробьям, но из песни слов не выкинешь — таков результат обсуждения этого кода в чате с кожаными программистами. Эффективность мне не нужна, кстати, мне нужен компактный способ записывать пары значений — из чего во что переходит.