На главную
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила раздела:
1. Название темы - краткое описание кто/что против кого/чего
2. В первом сообщении - список параметров, по которым идет сравнение.
3. Старайтесь аргументировать свои высказывания. Фразы типа "Венда/Слюникс - ацтой" считаются флудом.
4. Давайте жить дружно и не доводить обсуждение до маразма и личных оскорблений.
Модераторы: Модераторы, Комодераторы
Страницы: (3) [1] 2 3  все  ( Перейти к последнему сообщению )  
> Рассуждения на тему "С++ vs интерпретируемые языки"
    У всех языков свои особенности. Нельзя даже сказать что достоинства или недостатки. Где-то достоинства, а где-то недостатки.

    У C++ одна из основных ключевых фишек это итераторы. Везде и всегда итераторы. Ими можно осуществлять ввод, вывод, перебор, перестановку, перемещение, копирование, заполнение и так далее. Даже указать позицию для вставки или элемент для удаления.

    У C# его енумераторы, как-бы предоставляют базовую функциональность итераторов, но труба пониже, а дым пожиже. Можно перечислить коллекцию. Можно даже что-то сэмитировать. Но этого мало. А в итоге приходится огород городить. С другой же стороны в C# чуть иная объектная модель. Например, ту же задачу для C# я бы решил передав объект абстрактного типа TextWriter. А там уже пофиг какой именно объект StreamWriter, StringWriter или иное чудо-юдо.
    Но это корректно именно в C#. А для C++ просто так поток не передать. Ну, тоесть можно передать ссылку, а внутри хранить указатель на std::ostream. Раньше, кстати, именно так и делал, но такой код выглядит неестественным. Да уж, если говорить прямо, то старомодным. Использование чистых небезопасных указателей, это весьма рискованный ход повышающий шанс отстрелить себе ногу. К тому же это создаёт искуственные ограничения. А ведь до чего же удобно, записать текст прямо в строку, не дёргая потоки.

    У php и видимо большинства скриптовых языков, дела с итераторами и перечислениями обстоят ещё хуже. Ну что это за ботва, когда енумератор скрыт в самом контейнере? Да, на простых задачках это удобно и даже в чём-то упрощает жизнь. А что делать если надо два или три перечислителя? Тогда же приходится совсем жутко извращаться, доходя даже до полного дублирования самого контейнера. С другой же стороны, у скриптовых языков, проблемы типизации объектов, не стоят так остро и можно юзать трюки, которые в плюсах доступны лишь через шаблоны.

    Кстати, я внедоумении от файловых потоков в C++. Они, помоему, слишком ретроградны. Используют тоже один или два курсора, вместо итератора. А ведь эти потоки, можно и даже нужно рассматривать, как полноценные контейнеры вроде std::vector или std::list. Это позволило бы упростить алгоритмы и унифицировать внутренние сущности. Единственное что их оправдывает, так это обратная совместимость и традиционность.

    А касательно концептов, так их обещались добавить в C++17. Так что жду и недождусь.
    http://zouev.blogspot.ru/2009/07/blog-post_09.html

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

    Хорошо бы конечно добавить всякие самопроверки, чтоб выскакивали внятные ошибки, мол в указанном типе не реализован оператор * или =. А то этот код, вполне реально загнать в логический тупик с жуткой простынёй ошибок и предупреждений.

    Эта тема была разделена из темы "как передать произвольный итератор в скомпилированный класс?"
    Сообщение отредактировано: Eric-S -
    Человек должен делать то, что может сделать только он, всё остальное должна делать машина!
      Видя такой код, я все больше и больше испытываю, мягко говоря, "уныние" от ЯП со статической типизацией. И все эти уверения "да это же помощь программисту!" сродни украинским СМИ :lol:

      Что мы имеет по сути? Есть некоторая функция, которая берет на вход контейнер (ну не контейнер, а его части, отдаваемые итератором) и функциональный объект, производит обработку. И все. А сколько усилий для преодоления "помощи программисту" :lool:

      Цитата Eric-S @
      Ну что это за ботва, когда енумератор скрыт в самом контейнере? Да, на простых задачках это удобно и даже в чём-то упрощает жизнь. А что делать если надо два или три перечислителя?


      Вот нельзя так огульно за все языки говорить. Возьму и добавлю свой Энумератор.
      Более того, есть возможность с помощью метатаблиц переоперделить оператор [], но это уже другая тема, тут не буду.

      Пример на Lua:

      ExpandedWrap disabled
        -- инициализация -----------------------------------
         
        Array = {1,2," три ",4,5," шесть ",7,8,9}
         
        -- свойство таблицы --------------------------------
         
        function Array:EnumeratorEven(Idx)
          return Idx*2 > #self and nil or Idx*2
        end
         
        -- печать таблицы по определенному свойству  -------
         
        function PrintEven(Container)
          local I,R = 0,''
          repeat
            I = I + 1  
            local T = Array[Array:EnumeratorEven(I)]
            if T then R = R .. T else break end
          until (false)
          print("Res: " .. R)  
        end
         
        -- точка начала исполнения -------------------------
         
        PrintEven(Array)


      Я понимаю, код не Бог весть какой, но мне простительно - изучаю Lua только один день. Внезапно понадобилось. А вот теперь представим сколько тонн шаблонов из STL потянет! А тут - просто свойства и особенности языка.

      ЗЫ: Lua - второе "откровение" после Руби, в целом "просто отлично"!
      Мои программные ништякиhttps://majestio.info
        Цитата JoeUser @
        Видя такой код, я все больше и больше испытываю, мягко говоря, "уныние" от ЯП со статической типизацией. И все эти уверения "да это же помощь программисту!" сродни украинским СМИ :lol:

        Э, нет. Дело не в статической типизации. А в компиляции в машинный код.
        Я бы обошёлся бы без всего этого, если бы сделал функцию шаблонной. То есть, хоп, функция шаблонная, и мне обёртка нафиг не нужна.
        Только я захотел нешаблонную функцию, а значит поехали приключения.
        Что же касается интерпретируемых языков, то они ведь все шаблонные по определению.

        Далее, если бы у всех классов, был бы единый базовый класс, да ещё бы в стандартной библиотеки имелись огромные коллекции интерфейсов на все случии жизни, причём всё и всегда передавалось бы по указателю, то вопрос опять бы не стоял. Конечно, это всё можно сделать. Но стоить будет слишком дорого.
        Банальная виртуализация зачастую избыточна. А значит от неё можно и нужно избавиться.Пусть будет опциональной, лишь для тех кому она нужна.
        Объекты в динамической памяти излишняя роскошь. Мелочь можно хранить на стеке. А значит динамическая память только опционально, когда она действительно нужна.

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

        Конечно, C++ уже морально устарел. У него много недостатков, а развитие слишком медленное. Но именно C++ позволяет мне делать всякие вкусняшки, которые труднодостижимы в интерпретируемых языках. При всей своей крутизне, даже сайтостроители, отказываются от интерпретаторов, в пользу C и C++.

        У других языков, вроде D или Rust тоже есть свои вкусняшки. Но они в погоне за плюшками, потеряли этакую своеобразную наивную чистоту C++.
        Человек должен делать то, что может сделать только он, всё остальное должна делать машина!
          Цитата Eric-S @
          Но именно C++ позволяет мне делать всякие вкусняшки, которые труднодостижимы в интерпретируемых языках.

          Слабо верится :) Можно пример?
          Мои программные ништякиhttps://majestio.info
            Цитата JoeUser @
            Слабо верится :) Можно пример?

            Ну например частотный анализ звукового сигнала в реальном времени. Или даже банальная склейка фонем, опять же в реальном времени.
            Чтобы были бинарные буфера, которые поочереди подсовываются звуковухе для заполнения, а затем шерстятся несколькими алгоритмами вдоль и поперёк, определяя спектры частот, делают слепки, сравнивая их с базой данных, загруженной в память...

            А вот сейчас модернезирую обработку текста с распознанием внутренних лексических сущностей и моделированием разнообразных взаимодействий. Интерпретаторы от такого кошмарика ложатся из-за банальной нехватки памяти и быстродействия. Пробовал набрасывать отдельные элементы. Так разница по скорости обработки в тысячу раз.
            Ради интереса попробовал сделать загрузку и декодирование файлов на ruby... и озадачился кодировками. Почему-то не придумалось, как добавить парочку велосипедов. Да и хитрые алгоритмы поиска слов, не слишком удобно делать. Я лишь прикинул и решил, что не взлетит.

            Впринципе языки вроде rust, java, c# дают уже неплохую скорость. Но в них, труднее выразить некоторые абстракции, которые на C++ делаю банальным множественным наследованием. То есть языки с одиночным наследованием, ограничивают код по выразительности.

            Ах да, и конечно же, C++ позволяет мне обернуть вызов любой системной функции, с минимальными накладными расходами. Когда я написал словарь на C# (словарь в смысле базу данных специализированную для хранения и выборки слов), то очень огорчился низкой скоростью. На C++ этот же словарь (частично доделаный) работает гораздо быстрее. Ну да там ещё дело в конвертации типов данных и в маршализации. На C++ оно тоже получается быстрее и проще. А уж до чего прикольный конвертор получился на шаблонах... Я когда пытался повторить его на C# почти рыдал от невозможности прогнуть язык под свои хотелки.
            Сообщение отредактировано: Eric-S -
            Человек должен делать то, что может сделать только он, всё остальное должна делать машина!
              Цитата Eric-S @
              Интерпретаторы от такого кошмарика ложатся из-за банальной нехватки памяти и быстродействия. Пробовал набрасывать отдельные элементы. Так разница по скорости обработки в тысячу раз.


              Остается верить на слово :lol: На каком интерпретируемом ЯП ты это пробовал?
              Мои программные ништякиhttps://majestio.info
                Ты прав. В холиварах этому диалогу самое место.

                Цитата JoeUser @
                Остается верить на слово :lol: На каком интерпретируемом ЯП ты это пробовал?


                Глупо верить любым голословным утверждениям, даже моим.
                Ради справедливости, надо переписать и протестировать идентичный функционал. Тогда получатся более реальные тайминги.

                Я начинал на C#. Попробовал перенести на php, но почти сразу бросил, обнаружив тормоза и уперевшись в доступный объём памяти. php брал как единственный известный мне кросплатформенный язык, способный из коробки открывать и писать файлы.

                За образец функционала, точнее за идею, брал код спелчекера на nodejs и морфера на python. Они делали нечто похожее, но с функциональными ограничениями.

                Откровенно говоря, подходы и опирации различались.
                То есть функционал далеко неоднозначный.

                Суть алгоритма объяснять долго, поскольку некоторые моменты не выкрестолизовались в моей голове. Там много мелких нюансов. Возможно ещё буду приставать к народу по этому поводу.

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

                В конечном результате, программа, чисто эврестически должна создать словарь слов проставив каждому слову оценку его корректности.

                Там много всякого накручено, так что для более-менее адекватной синтетической замены, можно попробовать забацать классическую пузырьковую сортировку строк на огромном массиве.
                Сообщение отредактировано: Eric-S -
                Человек должен делать то, что может сделать только он, всё остальное должна делать машина!
                  Вообще читая всякие тесты когда один язык сравнивается с другим, я каждый раз замечал, что тестировщик либо пишет неоптимальный код, либо какой-то язык из коробки приспособлен лучше для решения конкретной задачи, чем другой.
                  Так что в идеале, надо сравнивать примеры кода, написанные упоротыми фанатиками конкретного языка. Но тогда опять же алгоритмы будут различатся, затрудняя сравнения.
                  А ещё смущают некоторые вставки... Например php-разработчик вызывает функцию написанную на C. И приэтом считает себя выйгравшим. Мол php быстрее чем C.
                  Человек должен делать то, что может сделать только он, всё остальное должна делать машина!
                    Цитата Eric-S @
                    Там много всякого накручено, так что для более-менее адекватной синтетической замены, можно попробовать забацать классическую пузырьковую сортировку строк на огромном массиве.


                    Ну давай сравним :lol: С тебя реализация на С++ исполняемого файла. Постановка задачи простая:

                    1) Прочитать из текстового файла, заданного как аргумент командной строки, текст
                    2) Разбить на слова, разделителями слов являются: пробел, знак табуляции, перевод строки, возврат каретки
                    3) Вывести в STDOUT все найденные слова в порядке убывания частот, в формате слово : число_посторений

                    А я все тоже самое сделаю на Perl, Ruby, Lua - и запущу для теста на своей машине, результаты отпищу тут.
                    Для теста попробую собрать "эталоны" текстовых файлов в 100Мb, 500Mb, 1Gb, 4Gb

                    Договорились?

                    Добавлено
                    Цитата Eric-S @
                    Например php-разработчик вызывает функцию написанную на C. И приэтом считает себя выйгравшим.

                    Имеет право :) Ты же на C++ используешь API ОС, не пишешь свои драйвера? Почему бы мне не пользоваться, к примеру, на том же Perl'е модулем, который юзает чужую динамическую либу, которая позволит мне перенести часть вычислений на GPU, просто, чтобы перегнать тебя и "наказать за самоуверенность" :lol:
                    Мои программные ништякиhttps://majestio.info
                      Цитата JoeUser @
                      Договорились?

                      Ох... И не лень?

                      Блин... Уже начал продумывать, как это дело заоптимизировать обходными трюками. Вот ведь маньяк. Не, это дело плохо пахнет.
                      Но так можно дойти и до использования стандартных функций и контейнеров.

                      Ладно... Я подумаю ещё. Может и напишу. Шибко оно похоже на "а тебе слабо?" От такого я бегу как от огня. Тем более стрёмно отстаивать честь C++, словно я самый крайний.

                      А вообще, надобы обговорить условия. Что можно использовать, а чего нельзя.
                      Очень хочется предложить повозможности использовать язык, а не его стандартную библиотеку. Но тут же возникает ощущение, что собираюсь обидеть ребёнка.

                      Цитата JoeUser @
                      Почему бы мне не пользоваться, к примеру, на том же Perl'е модулем, который юзает чужую динамическую либу, которая позволит мне перенести часть вычислений на GPU, просто, чтобы перегнать тебя и "наказать за самоуверенность" :lol:

                      Эх... Вот тут и вылизают недостатки синтетических тестов.
                      А зачем тогда вообще чего-то писать, если есть стандартные утилиты?

                      Вот ты предлагаешь выборку слова, определив конкретные разделители. Угу, тут всё просто, дёргаем функцию split или чего-нибудь вроде неё.
                      Но результат будет синтетический и нафиг ненужный.
                      Тоесть сам тест окажется притянутым зауши.

                      А как насчёт выборки реальных слов из реального текста? Там, где эти разделители хрен знает что. И уже хотя бы поэтому, стандартную функцию нельзя дёрнуть, а придётся писать свою функцию. Именно свою, поскольку в стандартных либах такой функции нет. Ну вот например знак '-' может разделять слова, а может быть внутри них. Знак точки может быть внутри слова, а может быть в конце предложения.

                      А как насчёт реального корректного сравнения слов? С учётом спецефичных особенностей? Слова надо раставить без учёта регистра, без учёта преффиксных и суффиксных символов и даже считая, но не ломая букву 'ё'?

                      Тут ведь подвох в самой задаче. Потому я и говорю, что мне ненравятся синтетические тесты. И сама задача надуманная. И условия подбираются так, чтоб компьютеру их было проще решить.

                      Я ведь не олемпиадник. И некоторые вещи из принципа делаю определённым образом. Например читаю и пишу файл потоками std::ifstream, std::ofstream. А тут, при постановке задачи, так и напрашивается открыть файл через CreateFilе. Я обычно использую стандартное выделение памяти, через vector или make_shared... Но тут так и хочется заюзать VirtualAlloc. То есть решение-то сильное, но далеко не жизненное.
                      И да, хочу заметить, что в большинстве известных мне интерпретаторов, включая и интерпретаторы байткода, используют спецефические менеджеры памяти. То есть будет очень даже справедливо, если я заюзаю тоже спецефический менеджер памяти.
                      Сообщение отредактировано: Eric-S -
                      Человек должен делать то, что может сделать только он, всё остальное должна делать машина!
                        Цитата Eric-S @
                        А как насчёт реального корректного сравнения слов? С учётом спецефичных особенностей? Слова надо раставить без учёта регистра, без учёта преффиксных и суффиксных символов и даже считая, но не ломая букву 'ё'?


                        В том-то и дело ... не нужно городить мозговыносный тест, что-то простое ... как сам сказал, без никаких либ, чисто инструментами языка.
                        Вот сам посуди. Пока ты размышлял о кораблях, бороздящих просторы тестов ... я собственно тест (тупо влоб) написал:

                        ExpandedWrap disabled
                          #!/usr/bin/perl
                          open (FD,$ARGV[0]) || die "Shit!";
                          map {$Freq{$_}++;} split /\s+/, join "", <FD>;
                          close (FD);
                          map {print $_." : ".$Freq{$_}."\n";} sort {$Freq{$b}<=>$Freq{$a}} keys %Freq;


                        Оптимизаций нуль. Но на малых текстах - твое время написания кода на С++, да плюс его выполнение - будут медленнее.
                        Уже медленее. Улавливаешь суть? :lol:

                        Добавлено
                        Цитата Eric-S @
                        Но тут так и хочется заюзать VirtualAlloc

                        На больших файлах - надо mmap, имхо. И по скорости, и по гемору - меньше.
                        Мои программные ништякиhttps://majestio.info
                          Цитата JoeUser @
                          Вот сам посуди. Пока ты размышлял о кораблях, бороздящих просторы тестов ... я собственно тест (тупо влоб) написал:

                          Вообще-то мне тупо лень сейчас чего-то писать. Зато есть огромное желание защитить результат от жульнечества. Если уж тестить, то результат должен быть максимально объективным.

                          Добавлено
                          Цитата JoeUser @
                          Но на малых текстах - твое время написания кода на С++, да плюс его выполнение - будут медленнее.

                          Это естественно. Как я писал ранее, задачи у языков разные.

                          Добавлено
                          Цитата JoeUser @
                          На больших файлах - надо mmap, имхо. И по скорости, и по гемору - меньше.

                          Может быть и так, но я эту тему вообще не колупал.
                          Человек должен делать то, что может сделать только он, всё остальное должна делать машина!
                            Цитата Eric-S @
                            Если уж тестить, то результат должен быть максимально объективным.

                            Ну пока то у тя и защищать-то нечего)

                            Добавлено
                            Цитата Eric-S @
                            Может быть и так, но я эту тему вообще не колупал.

                            Да тут все просто как грабли - управление чтением и размещением данных в страницах памяти ты отдаешь на откуп операционной системе ... а "не учишь её как ей правильно жить" :)
                            Мои программные ништякиhttps://majestio.info
                              Цитата JoeUser @
                              Пока ты размышлял о кораблях, бороздящих просторы тестов ... я собственно тест (тупо влоб) написал:

                              ExpandedWrap disabled
                                #!/usr/bin/perl
                                open (FD,$ARGV[0]) || die "Shit!";
                                map {$Freq{$_}++;} split /\s+/, join "", <FD>;
                                close (FD);
                                map {print $_." : ".$Freq{$_}."\n";} sort {$Freq{$b}<=>$Freq{$a}} keys %Freq;


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

                              Ну тупо в лоб и на C++ примерно так же:
                              ExpandedWrap disabled
                                ifstream f(argv[0]);
                                string word;
                                unordered_map<string, size_t> dict;
                                while (f >> word) ++dict[word];
                                vector<pair<string, int> > res;
                                res.reserve(dict.size());
                                copy(dict.begin(), dict.end(), back_inserter(res));
                                sort(res.begin(), res.end(), [](const auto & a, const auto & b) {return a.second > b.second;});
                                for (auto & w_c : res) cout << w_c.first << " : " << w_c.second << endl;

                              Не? :D
                              Код не проверял, если что
                              "If someone claims to have the perfect programming language, he is either a fool or a salesman or both"(c) Bjarne Stroustrup
                                Цитата D_KEY @
                                Код не проверял, если что

                                Норм код :)

                                Цитата D_KEY @
                                Не?

                                Ну а если по-честноку, то:

                                ExpandedWrap disabled
                                  #include <unordered_map>
                                  #include <algorithm>
                                  #include <iostream>
                                  #include <sstream>
                                  #include <vector>
                                   
                                  using namespace std;
                                   
                                  int main() {
                                      stringstream f("Мама мыла мыла раму");
                                      string word;
                                      unordered_map<string, size_t> dict;
                                      while (f >> word) ++dict[word];
                                      vector<pair<string, int> > res;
                                      res.reserve(dict.size());
                                      copy(dict.begin(), dict.end(), back_inserter(res));
                                      sort(res.begin(), res.end(), [](const auto & a, const auto & b) {return a.second > b.second;});
                                      for (auto & w_c : res) cout << w_c.first << " : " << w_c.second << endl;
                                      return 0;
                                  }


                                Т.е. +заголовки, +main, и +необработанный fstream. И это еще не все ... Это +подтягивание STL-а ...
                                А этого не хотел Eric-S, типа "давай без либ!". Я все исполнил честно :)

                                ЗЫ: Если с либами - заходим на http://www.cpan.org/ и выбираем модуль из которого будем писать программу в одну строчку :lol: Ну или почти ...
                                Мои программные ништякиhttps://majestio.info
                                1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                                0 пользователей:
                                Страницы: (3) [1] 2 3  все


                                Рейтинг@Mail.ru
                                [ Script Execution time: 0,1600 ]   [ 14 queries used ]   [ Generated: 25.01.20, 20:04 GMT ]