LINUX.ORG.RU

Продуктивность разработки на C++.

 , ,


6

12

Уважаемые программисты!

Предлагаю порассуждать о продуктивности разработки на C++ по сравнению с так называемыми скриптовыми языками. Вот, принято считать, что языки на вроде Python позволяют работать программисту более продуктивно по сравнению с C++. И что, дескать, на C++ надо писать только узкие места и всё такое.

Мне же хочется четкого понимания. Может быть это миф? А может быть это просто инерция, потому что так вот принято считать и все тут. Вот сегодня в C++ уже не надо думать об освобождении памяти, так как есть умные указатели. Сегодня есть уже более-менее нормальные IDE для C++. Так? Так.

Так что же тогда мешает писать на C++ столь же продуктивно, как на том же Python? Какие будут рассуждения? Может быть есть какие-то реальные обоснования на этот счёт, кроме как «в конторе Y так делают, значит смысл есть, они умные, им виднее». А может быть есть какие-то рецепты по продуктивности работы на C++?

Ответ на: комментарий от Eva

нужно писать в современном, функциональном стиле, чистые функторы, анонимные лямбды, метапрограммирование на шаблона

Ох-х-х... Для вас, теоретиков и любителей хитрой резьбы, есть Хаскель и прочие Лиспы. Си++ же для практических задач.

JacobTwoTwo
()
Ответ на: комментарий от Eva

А питон он без типов и для серьезных проектов не пригоден категорически, и gui там нет, второсортный язык, пригодный разве что для обучению программированию

Как без типов? В 3.5 завезли типы, а в 3.6 их улучшили. Для проверки есть mypy.

panter_dsd ★★★★
()
Ответ на: комментарий от panter_dsd

Как без типов? В 3.5 завезли типы, а в 3.6 их улучшили.

Тебе показалось, завезли аннотации которые ничего не делают.

anonymous
()
Ответ на: комментарий от invy

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

pon4ik ★★★★★
()
Ответ на: комментарий от panter_dsd

Для проверки есть mypy.

Он умеет выводить типы при множественном наследовании?

Eva
()
Ответ на: комментарий от azelipupenko

продуктивности работы с языком имеет посредственное отношение

Да. Но цель разработки не в том, чтобы писать код, а в том, чтобы написать его. Т.ч. формула эффективности использует не скорость писания текста, а время до сдачи готового. То, что отличие обусловлено разным определением «готовости» - в формулу не входит.

DonkeyHot ★★★★★
()

IDE и память это чушь. Чтобы разработка была продуктивной, нужна во-первых, адекватная стандартная библиотека (json распарсить одной строчкой, юникод, да банально строку разбить в вектор/список по whitespace, да хотя бы string.startswith), во-вторых минимум возможностей выстрелить себе в ногу. Второе решается опытом, первое в крупных компаниях типа G/FB/Y решается своей полноценной стандартной библиотекой. Вот при выполнении этих двух условий - да, продуктивность разработке на C++ ни на йоту не уступает тому же питону. Новичку же не знающему подводных камней оставшемуся один на один со стандартной библиотекой - увы.

slovazap ★★★★★
()

Какие будут рассуждения?

На пистоне можно говокодить, на си/плюсах - нельзя. Для управляемого кода с вм можно делать абстракции намного извратнее. Да, по скорости всё плохо, но для задачи это не критично, например.

А может быть есть какие-то рецепты по продуктивности работы на C++?

Делай работу таким инструментом, который для этого подходит, а не дрочи на яп.

crutch_master ★★★★★
()
Ответ на: комментарий от zolden

Приведу для 2-х, с позволения.

void fib(int n)
{
  int a = 0, b = 1;
  while (a < n) {
    std::cout << a << ' ';
    std::tie(a, b) = std::make_tuple(b, a + b);
  }
  std::cout << std::endl;
}

И фрукты:

void fruits()
{
  const std::vector<std::string> fruits = { "Banana", "Apple", "Lime" };
  std::vector<std::string> loud_fruits;
  for (auto f : fruits) {
    std::transform(begin(f), end(f), begin(f), toupper);
    loud_fruits.push_back(f);
  }

  std::list<std::pair<int, std::string>> list;
  for (decltype (fruits.size()) i = 0; i < fruits.size(); ++i)
    list.push_back(std::make_pair(int(i), fruits[i]));
}

azelipupenko
() автор топика
Ответ на: комментарий от yyk

Кодер, хорошо знающий плюсы и питон, сам решит не чём писать прикинув все за и против. Кодера, знающего только питон, к плюсам подпускать нельзя на пушечный выстрел :) Либо только после изучения всей цепочки «железо-коды-асм-си-...» :)

Плюсую

По ответам в треде можно легко понять кто насколько знает C++

Kroz ★★★★★
()

Как по мне, основная сложность плюсов состоит в походе.

Во-первых одно и то же можно сделать несколькими способами; а если их еще и комбинировать, то вообще получается треш. Это как в самом синтаксисе, так и во всяких библиотеках.

Во-вторых, есть определенные правила и best practices, которые собираются по крупицам, иногда кровью и потом. Например, не бросаться исключениями в деструкторе.

В-третьих, хороший код сделать можно, но многие ленятся это делать; например, многие забивают на const, noexcept, public/private, да хотя бы простую валидацию параметров в функции.

Ну, и чтобы код был читабельным, нужно продумать некоторые моменты.

Опытный человек это всё знает, и потому пишет нормальный код легко и непринужденно. Не очень опытный (я уже молчу о новичках) сделает венегрет, которого сам потом испугается, когда он разрастется.

Поэтому, если ты опытный с плюсами, то они вполне себе продуктивны. Если нет - нет.

Kroz ★★★★★
()
Ответ на: комментарий от slovazap

Второе решается опытом, первое в крупных компаниях типа G/FB/Y решается своей полноценной стандартной библиотекой.

Ну, к слову, с этим неплохо справляется Qt.

meliafaro ★★★★★
()
Ответ на: комментарий от meliafaro

Ну, к слову, с этим неплохо справляется Qt.

Ну да, хотел написать но потом забыл.

slovazap ★★★★★
()

Пролистал тред, не обнаружил смайлофага, царя, Евгения О. Скучно пока. Зайду на 5-й странице.

anonymous
()

Для чего-то мелкого и «одноразового» обычно продуктивнее использовать Python, для большого и с длительным периодом развития - С++. Иногда имеет смысл использовать их в связке.

anonymous
()

Так что же тогда мешает писать на C++ столь же продуктивно, как на том же Python?

у языков разная область применимости, там где можно эффективно писать на C++ часто неэффективно писать на python, и наоборот. тебе придется с этим жить

physical-protei
()
Ответ на: комментарий от physical-protei

там где можно эффективно писать на C++ часто неэффективно писать на python, и наоборот

осторожно, некоторые сектанты здесь думают что их язык единственно-верный. или это уже новый сотрудник троллит?

clover
()
Ответ на: комментарий от clover

осторожно, некоторые сектанты здесь думают что их язык единственно-верный. или это уже новый сотрудник троллит?

знаю. старый забыл перелогиниться :)

physical-protei
()
Ответ на: комментарий от panter_dsd

в плюсах make_tuple(action1(), action2()) тоже можно написать.

yoghurt ★★★★★
()
Ответ на: комментарий от anonymous

Тема избитая, уж чего-чего, а плюсовбросов на ЛОРе за 20 лет было хоть отбавляй.

yoghurt ★★★★★
()

С C++ сложно получить высокую продуктивность из-за огромного количества нюансов как самого языка, так и стандартной библиотеки.

На Python удобно писать прототипы программ или что-то вспомогательное. Возможно кто-то бекэнд на нём пишет. Но он не предназначен для мест, где критична скорость выполнения.

kachsheev ★★★
()
Ответ на: комментарий от pon4ik

Когда говоришь, что что-то ужасно, следует сразу выдать альтернативу, иначе, выглядит как-то голословно.

Может premake, там lua.

andreyu ★★★★★
()
Последнее исправление: andreyu (всего исправлений: 1)
Ответ на: комментарий от kachsheev

С C++ сложно получить высокую продуктивность из-за огромного количества нюансов как самого языка, так и стандартной библиотеки.

если ты считаешь что огромного числа нюансов нет в Python, то ты не знаешь python

clover
()
Ответ на: комментарий от andreyu

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

pon4ik ★★★★★
()

Так что же тогда мешает писать на C++ столь же продуктивно, как на том же Python?

Система типов же.
На питоне проще быстро наговнякать свою быдлопрограмму, но поддерживать позже сложнее. А через месяц ты перестанешь понимать принцип работы этой быдлопрограммы вообще.
На цепепе, очевидно, — наоборот. Хотя можно и на цепепе писать так, что ничего не поймёшь, но статическая типизация тебе всё же держит хоть в каких‐то рамках, а вот, например, javascript пропускает любой код быдлокод.

awesomelackware
()
Ответ на: комментарий от pon4ik

Ну вот в premake можно писать расширения на lua. К примеру для android написаны внешние модули.
Но я не могу сказать, что premake будет лучше и удобнее, чем cmake.
Во-первых, cmake более известен и у него комьюнити существенно шире. Во-вторых, его поддерживают многие проекты.
Чего нельзя сказать о premake, который много лет поддерживается одним человеком. Но зато там lua и весь конфиг - это скрипт на этом языке.

andreyu ★★★★★
()
Ответ на: комментарий от slovazap

json распарсить одной строчкой

void foo() { auto json = parse_json(R"{'key' : 'value'}");

юникод

???

да банально строку разбить в вектор/список по whitespace

  const std::string s{"this is a string"};
  std::istringstream is{s};
  std::string word;
  while (is >> word)
    std::cout << word << std::endl;

string.startswith

bool starts_with(const std::string& string, const std::string& pattern)
{
  return std::equal(pattern.begin(), pattern.end(), string.begin());
}

во-вторых минимум возможностей выстрелить себе в ногу

Не мог бы ты пояснить. Вот все говорят, в ногу, в ногу. А что это значит то?

Вот при выполнении этих двух условий - да, продуктивность разработке на C++ ни на йоту не уступает тому же питону.

Аргумент, да, согласен.

azelipupenko
() автор топика
Ответ на: комментарий от Eva

На С++ нужно писать в современном, функциональном стиле ...

Так я не об этом спрашиваю. Мне интересны доводы касаемо продуктивности. Все ругают C++ за то, что разработка на нём ведётся через боль, что писать на нём долго и мучительно. Но при этом те же самые люди говорят, что C++ альтернатив нет, что быстрее ничего не работает, что компилятор в нём отлавливает кучу ошибок и так далее.

При этом, если посмотреть на всякие компании, то у них принято почему-то писать на Python. Вот мне и стали интересны объективные критерии выбора Python. Почему пишут ещё и на нём, а не только на C++. И возможно ли в принципе использовать C++ так же, как используется Python.

А питон он без типов и для серьезных проектов не пригоден категорически

Ну не знаю, что ты подразумеваешь под серьезными проектами.

azelipupenko
() автор топика
Ответ на: комментарий от azelipupenko
void foo() { auto json = parse_json(R"{'key' : 'value'}");

Петросянство комментировать не буду.

  const std::string s{"this is a string"};
  std::istringstream is{s};
  std::string word;
  while (is >> word)
    std::cout << word << std::endl;

Спасибо, отличная иллюстрация почему C++ по умолчанию непродуктивен.

bool starts_with(const std::string& string, const std::string& pattern)
{
  return std::equal(pattern.begin(), pattern.end(), string.begin());
}

А вот и отличная иллюстрация почему в C++ легко выстрелить в ногу. UB сам найдёшь?

slovazap ★★★★★
()
Ответ на: комментарий от azelipupenko

При этом, если посмотреть на всякие компании, то у них принято почему-то писать на Python

А не надо смотреть на «всякие» компании.

anonymous
()
Ответ на: комментарий от crutch_master

На пистоне можно говокодить, на си/плюсах - нельзя.

Это ещё почему? Я всегда полагал, что писать кривой код можно на любом языке.

Делай работу таким инструментом, который для этого подходит, а не дрочи на яп.

Хорошо. Вот нужно _с нуля_ написать сетевой сервер. Допустим, пусть будет HTTP-сервер. Какой язык программирования ты бы для этого взял и почему?

PS Не надо спрашивать зачем писать HTTP-сервер с нуля в 2017 году. Топик про процесс разработки чего бы то ни было, не важно чего.

azelipupenko
() автор топика
Ответ на: комментарий от Eva

Короче, современные домохозяйки выбирают Си-плас-плас!

Virtuos86 ★★★★★
()
Ответ на: комментарий от slovazap

Как раз говнокодить на плюсах намного проще.

Скорее говнокодить на плюсах намного опаснее.

anonymous
()
Ответ на: комментарий от azelipupenko

Ну не знаю, что ты подразумеваешь под серьезными проектами

например Microsoft Office, MSSQL Server, Exchange

Eva
()
Ответ на: комментарий от slovazap

Петросянство комментировать не буду.

Почему Петросянство? Не уж то нет библиотек, которые умеют парсить JSON одной строчкой кода? Мне просто лень искать, но что нереального я написал?

Спасибо, отличная иллюстрация почему C++ по умолчанию непродуктивен.

Т.е. в Python можно сделать проще?

А вот и отличная иллюстрация почему в C++ легко выстрелить в ногу. UB сам найдёшь?

Что-то не находится.

azelipupenko
() автор топика
Ответ на: комментарий от azelipupenko

Т.е. в Python можно сделать проще?

Да

In [1]: 'foo bar baz'.split()
Out[1]: ['foo', 'bar', 'baz']

Что-то не находится.

Подозреваю, он в случае, когда паттерн больше самой строки

Deleted
()
Последнее исправление: ecko (всего исправлений: 1)
Ответ на: комментарий от azelipupenko

std::equal(pattern.begin(), pattern.end(), string.begin());
Что-то не находится.

Если string пустой, то string.begin() имеет полное право вернуть nullptr. Не считая того, что для непустой строки, итератор не обязательно должен прийти к \0 (хотя по факту сделать иначе можно разве что специально).

anonymous
()
Ответ на: комментарий от Deleted

когда паттерн больше строки, пистон сам более другим языкам отсосет.

from abc import ABCMeta, abstractmethod

class Observer(metaclass=ABCMeta):
    """
    Абстрактный наблюдатель
    """

    @abstractmethod
    def update(self, message: str) -> None:
        """
        Получение нового сообщения
        """
        pass

class Observable(metaclass=ABCMeta):
    """
    Абстрактный наблюдаемый
    """

    def __init__(self) -> None:
        """
        Constructor.
        """
        self.observers = []     # инициализация списка наблюдателей

    def register(self, observer: Observer) -> None:
        """
        Регистрация нового наблюдателя на подписку
        """
        self.observers.append(observer)

    def notify_observers(self, message: str) -> None:
        """
        Передача сообщения всем наблюдателям, подписанным на события
        данного объекта наблюдаемого класса
        """
        for observer in self.observers:
            observer.update(message)

class Newspaper(Observable):
    """
    Газета, за новостями в которой следят тысячи людей
    """

    def add_news(self, news: str) -> None:
        """
        Выпуск очередной новости
        """
        self.notify_observers(news)

class Citizen(Observer):
    """
    Обычный гражданин, который любит читнуть с утра любимую газетку
    """

    def __init__(self, name: str) -> None:
        """
        Constructor.

        :param name: имя гражданина, чтоб не спутать его с кем-то другим
        """
        self.name = name

    def update(self, message: str) -> None:
        """
        Получение очередной новости
        """
        print('{} узнал следующее: {}'.format(self.name, message))

if __name__ == '__main__':
    newspaper = Newspaper()                 # создаем небольшую газету
    newspaper.register(Citizen('Иван'))     # добавляем двух человек, которые
    newspaper.register(Citizen('Василий'))  # ... ее регулярно выписывают
    # ... и вбрасываем очередную газетную утку
    newspaper.add_news('Наблюдатель - поведенческий шаблон проектирования')

'''
Иван узнал следующее: Наблюдатель - поведенческий шаблон проектирования
Василий узнал следующее: Наблюдатель - поведенческий шаблон проектирования
'''

На Io:

Observer := Object clone

Observable := List clone do(
   register := getSlot("push")
   notify := method(message, self foreach(observer, observer update(message)))
)
Newspaper := Observable clone do( addNews := method(news, notify(news)))

Citizen := Observer clone do(
   create := method(name, self clone lexicalDo(name := name))
   update := method(message, writeln( name .. " узнал следующее: " .. message))
)

newspaper := Newspaper clone

newspaper do(
   register(Citizen create("Иван"))
   register(Citizen create("Василий"))
   addNews("Наблюдатель - поведенческий шаблон проектирования")
)

#>>>> Иван узнал следующее: Наблюдатель - поведенческий шаблон проектирования
#>>>> Василий узнал следующее: Наблюдатель - поведенческий шаблон проектирования

onceagain2017
()
Ответ на: комментарий от onceagain2017

Ты кто? Какого чёрта ты делаешь у меня в уведомлениях? Я говорил что-то о паттернах?

Человек задал два вопроса и получил от меня два ответа. За паттернами иди спорить с другими.

Deleted
()
Ответ на: комментарий от anonymous

И где эта проверка должна сработать?

Это не проверка, это основы STL. А проверки в реализациях алгоритмов STL.

azelipupenko
() автор топика
Ответ на: комментарий от azelipupenko

Это не проверка, это основы STL. А проверки в реализациях алгоритмов STL.

Сдается мне, что ты жирный тролль.

anonymous
()
Ответ на: комментарий от anonymous

Сдается мне, что ты жирный тролль.

Это почему еще?

azelipupenko
() автор топика
Ответ на: комментарий от Deleted

Подозреваю, он в случае, когда паттерн больше самой строки

А в Python можно допустить такую ошибку? Это будет называться прострелом ноги?

azelipupenko
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.