LINUX.ORG.RU

Существует ли язык высокого уровня, который устойчиво быстрее C?

 ,


0

1

Возможно ли сделать язык программирования, который не будет содержать платформ-зависимых операций, но при этом позволит получить у готовой программы производительность не меньше чем у оптимально написанной программы на C?

Понятно что существует ассемблер, программу на котором можно сделать настолько быстрой, насколько это вообще возможно для данной машины за счёт контроля каждого байтика, но речь не о нём — я говорю о языке высокого уровня, который полностью абстрагируется от машины, так чтобы программа на нём могла быть скомпилирована на любой машине и для любой ОС.

Так вот, возможно ли сделать такой язык? Если да, то в каком направлении копать?

А может уже существуют такие языки, просто из-за популярности C на них мало кто пишет, поскольку всплывают проблемы совместимости с существующей базой уже готового кода?

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

Это не задача, а дерьмо.

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

А уж если я тебя спрошу зачем мне «уникализировать» и «посчитать число вхождений» - где это применяется в реальном ире - ты обделаешься.

Задача реальная это «есть датасет», формат которого определяется мною, а вродящие данные средой. И описывается результата - всё. Никаких условий. Никаких кастылей уровня реализации в задачу не закладывается.

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

Просто покажи код, к которому применимо то, о чем ты говоришь.

Ну хорошо :-) Пусть требуется удалить все пробелы по краям строки перед выводом её на экран :-) Для этого был написан простой велосипед, который в нижеследующем тесте запускается 10 миллионов раз:

/* (C) :-) */
#include <assert.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

/* My bicycle :-) */
static char *trim(char *s)
{
     while (isspace(*s)) ++s;
     int l;
     if ((l = strlen(s)) > 0) {
          char *e = s + l - 1;
          while (isspace(*e)) --e;
          e[1] = '\0';
     }
     return s;
}

int main(int argc, char *argv[])
{
     char *const test = strdup("       :-) :-)                   ");
     const char *trims;
     for (int i = 0; i < 10000000; ++i)
           trims = trim(test);
     printf("%s\n", trims);
     free(test);
     return 0;
}

А это решение с использованием «стандартного средства» - великого и ужасного boost, которое также запускается 10 миллионов раз:

// (C) :-)
#include <boost/algorithm/string/trim.hpp>

#include <iostream>
#include <string>

int main(int argc, char *argv[])
{
  std::string test("       :-) :-)                   ");
  for (int i = 0; i < 10000000; ++i)
    boost::algorithm::trim(test);
  std::cout << test << std::endl;
  return 0;
}
Данное сравнение не честно по отношению к моему велосипеду на C, потому что мой велосипед честно триммирует строку все 10 миллионов итераций, в то время как версия на C++ триммирует строку только на 1-й итерации :-) Чтобы заставить цепепешную версию с использованием вышеупомянутых «стандартных» готовых средств триммировать строку 10 миллионов итераций, копирования не избежать, т.е. это либо boost::algorithm:trim_copy, либо копирование строки перед передачей ссылки на неё в boost::algorithm::trim :-) Но это будет такой тормоз, что 10 миллионов итераций я ждать не хочу :-) Поэтому я сжалился над цепепешной версией и оставил так, как есть :-) Результаты:
tests $ gcc -O3 -otrim trim.c
tests $ g++ -O3 -otrim+ trim.cpp
tests $ time ./trim
:-) :-)

real	0m0.205s
user	0m0.200s
sys	0m0.000s
tests $ time ./trim+
:-) :-)

real	0m1.341s
user	0m1.336s
sys	0m0.004s
Стандартное решение из великого boost слило моему велосипеду в 6 раз :-) Бугага :-)

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

Назови хотя бы одну реальную задачу, в которой были бы нужны твои убогие хипсторские «регулярки».

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

Назови хотя бы одну реальную задачу, в которой были бы нужны твои убогие хипсторские «регулярки».

Давай я назову :-) Задача описать одним выражением множество строк, каждая из которых соответствует правилам, указанным в выражении :-) Применение: от текстового редактора до grep(1), до NGINX и др. web-серверов :-)

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

Стандартное решение из великого boost слило моему велосипеду в 6 раз :-) Бугага :-)

А ты действительно веселый дурачок. Аналог твоего кода на бусте будет trim_if(test, isspace). А теперь еще раз сравни.

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

Регулярные выражения сложней a*b или a??b придумали гомосеки!

Если даже и так, то что с того? :-) Говорят, Чайковский тоже был другим :-) Его музыка прекрасна :-)

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

другим

Лучше бы их на удобрения отправляли!

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

Аналог твоего кода на бусте будет trim_if(test, isspace). А теперь еще раз сравни.

Ой, точно, просто не стал читать, чтобы понять, что есть trim_if вот это:

namespace boost {
  namespace algorithm {
    template<typename OutputIteratorT, typename RangeT, typename PredicateT> 
      OutputIteratorT 
      trim_left_copy_if(OutputIteratorT, const RangeT &, PredicateT);
    template<typename SequenceT, typename PredicateT> 
      SequenceT trim_left_copy_if(const SequenceT &, PredicateT);
    template<typename SequenceT> 
      SequenceT trim_left_copy(const SequenceT &, 
                               const std::locale & = std::locale());
    template<typename SequenceT, typename PredicateT> 
      void trim_left_if(SequenceT &, PredicateT);
    template<typename SequenceT> 
      void trim_left(SequenceT &, const std::locale & = std::locale());
    template<typename OutputIteratorT, typename RangeT, typename PredicateT> 
      OutputIteratorT 
      trim_right_copy_if(OutputIteratorT, const RangeT &, PredicateT);
    template<typename SequenceT, typename PredicateT> 
      SequenceT trim_right_copy_if(const SequenceT &, PredicateT);
    template<typename SequenceT> 
      SequenceT trim_right_copy(const SequenceT &, 
                                const std::locale & = std::locale());
    template<typename SequenceT, typename PredicateT> 
      void trim_right_if(SequenceT &, PredicateT);
    template<typename SequenceT> 
      void trim_right(SequenceT &, const std::locale & = std::locale());
    template<typename OutputIteratorT, typename RangeT, typename PredicateT> 
      OutputIteratorT 
      trim_copy_if(OutputIteratorT, const RangeT &, PredicateT);
    template<typename SequenceT, typename PredicateT> 
      SequenceT trim_copy_if(const SequenceT &, PredicateT);
    template<typename SequenceT> 
      SequenceT trim_copy(const SequenceT &, 
                          const std::locale & = std::locale());
    template<typename SequenceT, typename PredicateT> 
      void trim_if(SequenceT &, PredicateT);
    template<typename SequenceT> 
      void trim(SequenceT &, const std::locale & = std::locale());
  }
}
Быстрее было написать на C :-) И это не аналог, т.к. trim_if() триммирует 1 раз, а мой велосипед - все 10 миллионов итераций :-) И всё равно, цепепе слил, даже здесь:
tests $ time ./trim
:-) :-)

real	0m0.148s
user	0m0.148s
sys	0m0.000s
tests $ time ./trim+
:-) :-)

real	0m0.193s
user	0m0.192s
sys	0m0.000s

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

Ой, точно, просто не стал читать, чтобы понять, что есть trim_if вот это:

Ты просто не стал читать. В доке написано про _if варианты.

Быстрее было написать на C :-)

Ага, каких-то «10 минут» (с) для простой задачи, что может быть быстрее.

И это не аналог, т.к. trim_if() триммирует 1 раз, а мой велосипед - все 10 миллионов итераций :-)

Т.е. ты сам в своем коде не видишь изменение оригинальной строки?

И всё равно, цепепе слил, даже здесь:

У тебя ус отклеился время изменилось с предыдущего поста. У меня практически вровень, плюс-минус погрешность.

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

Ага, каких-то «10 минут» (с) для простой задачи, что может быть быстрее.

1 минута :-)

Т.е. ты сам в своем коде не видишь изменение оригинальной строки?

Это ты не видишь, что в моём коде в trim() каждый раз передаётся оригинальная строка - test :-)

У тебя ус отклеился время изменилось с предыдущего поста. У меня практически вровень, плюс-минус погрешность.

Так я же и тест-кейс на C изменил, чтобы он соответствовал тест-кейсу на цепепе :-) Благо це это позволяет, в отличии от цепепе:

/* (C) :-) */
#include <assert.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

/* My bicycle :-) */
static inline char *trim(char *s)
{
     while (isspace(*s)) ++s;
     int l;
     if ((l = strlen(s)) > 0) {
          char *e = s + l - 1;
          while (isspace(*e)) --e;
          e[1] = '\0';
     }
     return s;
}

int main(int argc, char *argv[])
{
     char *const test = strdup("       :-) :-)                   ");
     char *trims = test;
     for (int i = 0; i < 10000000; ++i)
           trims = trim(trims);
     printf("%s\n", trims);
     free(test);
     return 0;
}
Теперь тест-кейсы эквивалентны :-) Возьми и запусти :-) И кто из нас дурачок? :-)

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

1 минута :-)

Ты скромничаешь.

Это ты не видишь, что в моём коде в trim() каждый раз передаётся оригинальная строка - test :-)

А это что:

e[1] = '\0';

Т.е. ты сам не разбираешься в предрставленном коде. Скопипастил небось.

Возьми и запусти :-)

Все так же без разницы, около 0.17-0.18 сек на оба варианта.

И кто из нас дурачок? :-)

Спросим у зрительного зала.

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

Ты скромничаешь.

Ну я скромен :-)

А это что: e[1] = '\0';

Это запись по адресу, на который указывает e + 1 :-) Теперь открой глаза и подумай :-)

Все так же без разницы, около 0.17-0.18 сек на оба варианта.

Не мои проблемы :-)

Спросим у зрительного зала.

Гыгы :-)

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

Это запись по адресу, на который указывает e + 1 :-) Теперь открой глаза и подумай :-)

Ну вот ты и скатился в откровенную клоунаду.

Не мои проблемы :-)

Конечно. Все хорошо.

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

Это запись по адресу, на который указывает e + 1 :-) Теперь открой глаза и подумай :-)

А смайлик-то еще больший идиот, чем можно было себе представить:

#include <assert.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

/* My bicycle :-) */
static inline char *trim(char *s)
{
     while (isspace(*s)) ++s;
     int l;
     if ((l = strlen(s)) > 0) {
          char *e = s + l - 1;
          while (isspace(*e)) --e;
          e[1] = '\0';
     }
     return s;
}

int main(int argc, char *argv[])
{
     char *const test = strdup("       :-) :-)                   ");
     char *trims = test;
     trims = trim(trims);
     printf("trims: '%s', test: '%s'\n", trims, test);
     free(test);
     return 0;
}
Результат: trims: ':-) :-)', test: ' :-) :-)'

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

Ну вот ты и скатился в откровенную клоунаду.

А что не так? :-) Ещё раз повторяю - строка оригинальная :-) Мало ли что в адресе, на который указывает e + 1 после 1-й итерации будет 0 :-) Ну ладно, не парься :-) В моей версии после первой итерации алгоритм будет усекать лишь те пробелы, что слева :-) Но строка всё равно оригинальная, в широком смысле :-) Гг :-)

Конечно. Все хорошо.

Конечно цепепе слил :-) На моё компе это так :-)

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

А смайлик-то еще больший идиот, чем можно было себе представить

Полёт твоей фантазии велик :-) Правда только в твоих фантазиях :-) Гг :-)

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

Но строка всё равно оригинальная, в широком смысле :-) Гг :-)

В варианте с boost - аналогично.

Конечно цепепе слил :-) На моё компе это так :-)

Мои поздравления.

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

Мои фантазии оставьте мне. А вот то, что вы агитируете за С, при этом нормально на C писать не можете... Вот это что? Заблуждение или диагноз?

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

Ты умудрился слить даже в задаче, которую сам привел. Жесть.

Ещё один поциент :-) Ну и где же слив? :-)

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

В варианте с boost - аналогично.

Т.е. я на уровне с разработчиками boost :-)

Мои поздравления.

Вау, спасибо! :-)

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

Ты тупой, да? Я просил *реальную* задачу, а ты про какие-то множества-хреножества бормочешь.

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

И что в моём коде не так? :-)

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

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

Ну и где же слив? :-)

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

Так ответь, зачем велосипедить?

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

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

Бугага :-) Я не замечал, что модифицирую исходную строку? :-) Ты глянь, реально клоун :-) Думает, что я написал сигнатуру trim(char *), а не trim(const char*) и не замечал, что модифицирую память по указателю не на константу :-) Тебя от 20 лет цепепе совсем что-ли повело? :-)

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

Во-первых, код - говно.

Почему он говно? :-) Обоснуй, иначе слив :-)

Во-вторых, он портит вход.

Слив засчитан :-) Он это делает для эффективности :-) Как это делает и trim/trim_if из boost :-)

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

Слив засчитан :-) Я привёл результаты :-)

Так ответь, зачем велосипедить?

Слив засчитан :-)

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

Слив засчитан :-)

Ты струсил даже опубликовать рядом два варианта кода, которые мерял.

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

Бугага :-) Я не замечал, что модифицирую исходную строку? :-)

Более того, вы даже не заметили, как сами это признали:

А что не так? :-) Ещё раз повторяю - строка оригинальная :-) Мало ли что в адресе, на который указывает e + 1 после 1-й итерации будет 0 :-) Ну ладно, не парься :-) В моей версии после первой итерации алгоритм будет усекать лишь те пробелы, что слева :-) Но строка всё равно оригинальная, в широком смысле :-) Гг :-)

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

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

Ты тупой, да? Я просил *реальную* задачу, а ты про какие-то множества-хреножества бормочешь.

Само ты тупое, да :-) Я тебе выкатил задачу - описать множество строк одним выражением :-) Нахрен мне далось для тупого поиска строчек в файле, над которым работаю, писать кучу разных строк для поиска, если я могу написать одно выражение? :-) Упоролся что-ли?

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

Почему он говно? :-)

Ну, например, из-за strlen. На больших строках твоя функция просядет и будет бесполезно лопатить память.

Как это делает и trim/trim_if из boost :-)

В boost есть еще и _copy варианты.

// Другой Анонимус

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

Более того, вы даже не заметили, как сами это признали:

Слив засчитан :-) Вот оно, влияние цепепе :-) Повторяю ещё раз - строка оригинальная - т.е. это строка, которую высрал strdup() :-) И то, что в e + 1 записался 0 не привело к переаллокации памяти :-) Строка оригинальная :-)

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

И даже при таких замерах boost слил смайлику :-)

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

Ну, например, из-за strlen. На больших строках твоя функция просядет и будет бесполезно лопатить память.

Давай пруф :-)

В boost есть еще и _copy варианты.

Я об этом говорил :-) Или читай весь тред, или не впрягайся со своими взвяками :-)

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

Строка оригинальная :-)

Вы настолько тупы безграмотны, что не различаете «буфер» и «строку». Буфер у вас один и тот же (даже непонятно, зачем вообще нужен был strdup и последующий free). А вот строка поменялась после переноса терминального ноль-символа.

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

Давай пруф :-)

Пруф чего? Того, что время работы strlen зависит от длины строки? Ну вот, например:

https://www.gnu.org/software/m68hc11/examples/bench-string.html

Явно виден линейный рост.

Я об этом говорил :-) Или читай весь тред, или не впрягайся со своими взвяками :-)

Ты об этом говорил, а в boost уже есть. В итоге ты будешь опять велосипедить.

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

Вы настолько тупы безграмотны, что не различаете «буфер» и «строку».

Причём тут буфер? :-) Я пользовался strdup(), а не каким-то bufdup() :-)

(даже непонятно, зачем вообще нужен был strdup и последующий free)

Слив засчитан :-) А теперь я тебе, безграмотному цепепешнику объясню зачем я это сделал :-) Сейчас ты попался на том, что без strdup() функция trim() попыталась записать в константу и получился бы Segmentation fault :-) А free() нужен чтобы память освободить несмотря на то, что это перед завершением программы :-) Ты обделался :-)

А вот строка поменялась после переноса терминального ноль-символа.

Поменялось содержимое e + 1 :-)

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

Я тебе выкатил задачу - описать множество строк одним выражением

Это не реальная задача, баран. В реальном мире нет никаких «множеств строк». Чтобы плавилась сталь и колосилась рожь твои хипсторские регулярные выражения не нужны.

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

У тебя на него персональный разрыв пукана? Тогда все ясно.

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

Причём тут буфер?

При том, что строка в C — это всего лишь последовательность символов в памяти, завершающаяся терминальным ноль символом. Соответственно, под хранение строки должна быть выделена какая-то память. Кусок этой памяти будет тем самым буфером, хранящим строку.

К strdup или bufdup это не имеет никакого отношения.

А теперь я тебе, безграмотному цепепешнику объясню зачем я это сделал :-) Сейчас ты попался на том, что без strdup() функция trim() попыталась записать в константу и получился бы Segmentation fault :-)

Идиот, вы все равно в trim-е модифицируете значение по переданному в trim указателю. Соответственно, вы могли бы обойтись размещением буфера для хранения строки просто на стеке:

char test[] = "bu-ga-ga :)";
char * trims = test;
И константность в вашем примере идет лесом, так что вы вообще зря ее привлекли.

Поменялось содержимое e + 1 :-)

Матчасть поучите. Может поймете, как эта конструкция влияет на значение строки.

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

При том, что строка в C — это всего лишь последовательность символов в памяти, завершающаяся терминальным ноль символом.

Не надо мне это говно рассказывать :-) Я знаю эту всю хрень :-)

Соответственно, вы могли бы обойтись размещением буфера для хранения строки просто на стеке:

Так сделать можно :-)

И константность в вашем примере идет лесом, так что вы вообще зря ее привлекли.

Слив засчитан :-) Попробуй вызови trim(" :-) :-) ") :-)

Матчасть поучите. Может поймете, как эта конструкция влияет на значение строки.

Бугага :-)

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

Это не реальная задача, баран. В реальном мире нет никаких «множеств строк».

Само ты боран :-) В реальном мире есть Emacs, в котором я работаю :-) И мне иногда нужно указывать множество строк регуляркой :-)

Чтобы плавилась сталь и колосилась рожь твои хипсторские регулярные выражения не нужны.

Ну и насрать :-)

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

Слив засчитан :-) Попробуй вызови trim(" :-) :-) ") :-)

Смайлик, вы, блин, реально не видите разницы между константным указателем на неконстантную строку (тот самый char *const test = strdup из вашего первоначального примера) и указателем на константную строку?

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

Смайлик, вы, блин, реально не видите разницы между константным указателем на неконстантную строку (тот самый char *const test = strdup из вашего первоначального примера)

*const test тут потому, что я не собирался менять test - т.е. указатель :-)

и указателем на константную строку?

Фух :-) Это ты не догоняешь :-) Попробуй сделать так:

"Zhopa"[1] = 0;

Скорее всего, словишь SIGSEGV :-)

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

Скорее всего, словишь SIGSEGV :-)

Етить-колотить... Хорошо хоть, что эта тема позволила выяснить, что царь — шизофреник, а смайлик — идиот.

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