LINUX.ORG.RU

конкурс по си

 ,


7

4

На опеннете есть новость про то как сотрудник redhat шлёт левые патчи в ядро чтобы обойти проблемы systemd (http://www.opennet.ru/opennews/art.shtml?num=39476). Собстно, вот патчик:

http://lkml.iu.edu//hypermail/linux/kernel/1404.0/01327.html

Имхо, это ужас. Вот уж действительно товарищ принял упорин. Во-первых, он так и не понял почему редактирование /proc/cmdline это зло. Во-вторых, код ужасен, не? Неужели в сях нет способа проще вырезать подстроку? Ну и само по себе использование «магических» цифр 4 и 5 позорит код.

Так вот, конкурс по вырезанию произвольного слова из строки объявляю открытым! Учтите что слово может встречаться несколько раз.

★★★★★

Последнее исправление: beastie (всего исправлений: 2)

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

ради сомнительной экономии тактов

Я, честно говоря, не думаю что стояла такая цель. Если стояла то они реально упороты. Но, мне кажется, чувак просто писал как мог.

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

а как же комменты на моё изделие?!?

не ужели зафильтрован :(

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

Но, мне кажется, чувак просто писал как мог.

Наверняка. Вон, на БХ рекламировали некую PVS-студию. Проверили ею код сайлаба и возмущались, мол, как же так: такое количество дыр и очепяток. А вот интересно, намного ли отличается проприетарщина? Судя по глюкам, то же самое. Только народ-то баксы платит!

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

по всякому бывает

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

char s[100]; *s = 0;

char s[100]; s[0] = 0; // устроил отца русской демократии

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

ну алгоритмически всёж стоить выкусывать с конца строки иначе ты сколько раз встретиш вхождения столько раз хвост скопируеш.

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

т.е strcpy тут не к месту.

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

имхо

inline char*nxt(char* s){while(isalpha(*++s));return s;}
//fill space in memory
char*
wordstrips(char *src, char * needle)
{
        if(!*needle)return src;
        int n=strlen(needle);
        char *l=src-1,*r;
        do{
                r=nxt(l);
                if(r-++l!=n)continue;
                if(strncmp(l,needle,n))continue;
                while(l<r)*l++=' ';
        }while(*(l=r));
        return src;
}

мнится быстрее , да и адекватней исходной(добавлено многократное удаление) задаче.

может замутиш тесткейсы для сравнения ?

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

выкладывай

Вот код для забивания пробелами:

void remove_word( char* s, const char* w )
{
    int l = strlen( w );
    char* p = s;
	
    while( p = strstr( p, w ) )
    {
        if( ( p == s || isspace( p[ -1 ] ) ) && ( !p[ l ] || isspace( p[ l ] ) ) )
            memset( p, ' ', l );

        p += l;
    }
}

для удаления запощу после твоего аналогичного

wota ★★
()
Последнее исправление: wota (всего исправлений: 1)
Ответ на: комментарий от qulinxao
~$ cat 1.c
#include <ctype.h>
#include <string.h>

static inline char*nxt(char* s){while(isalpha(*++s));return s;}
//fill space in memory
char*
wordstrips(char *src, char * needle)
{
        if(!*needle)return src;
        int n=strlen(needle);
        char *l=src-1,*r;
        do{
                r=nxt(l);
                if(r-++l!=n)continue;
                if(strncmp(l,needle,n))continue;
                while(l<r)*l++=' ';
        }while(*(l=r));
        return src;
}

int main()
{
        char* str = "длинная строка, в которой строка - текст, который строка удалить надо строка вот";
        int i = 0;

        for( ; i < 10000000 ; ++i )
        {
                char buf[ 256 ];
                strcpy( buf, str );
                wordstrips( buf, "строка" );
        }

        return 0;
}
~$ gcc -O2 1.c  
~$ time ./a.out 

real    0m1.743s
user    0m1.739s
sys     0m0.002s
~$ time ./a.out 

real    0m1.746s
user    0m1.743s
sys     0m0.001s



~$ cat 2.c
#include <ctype.h>
#include <string.h>

void remove_word( char* s, const char* w )
{
    int l = strlen( w );
    char* p = s;

    while( p = strstr( p, w ) )
    {
        if( ( p == s || isspace( p[ -1 ] ) ) && ( !p[ l ] || isspace( p[ l ] ) ) )
            memset( p, ' ', l );

        p += l;
    }
}

int main()
{
    char* str = "длинная строка, в которой строка - текст, который строка удалить надо строка вот";
    int i = 0;

    for( ; i < 10000000 ; ++i )
    {
        char buf[ 256 ];
        strcpy( buf, str );
        remove_word( buf, "строка" );
    }

    return 0;
}
~$ gcc -O2 2.c
~$ time ./a.out 

real    0m0.822s
user    0m0.820s
sys     0m0.001s
~$ time ./a.out 

real    0m0.826s
user    0m0.824s
sys     0m0.001s
wota ★★
()
Ответ на: комментарий от wota

Я смотрю, у большинства один и тот же грубый косяк: либо правится исходная строка, либо возвращается строка в объеме, равном исходной.

Память-то не резиновая!

Или тут одни разработчики хромых с тормозилами собрались?

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

Я смотрю, у большинства один и тот же грубый косяк: либо правится исходная строка
Память-то не резиновая!

/0

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

А теперь сделай тест: пусть src будет строкой длиной 10кБ, needle пусть будет длиной 10Б и пусть оно встречается 500 раз в src. Сделай 10000 копий src и в каждой поудаляй needle.

Теоретически после этого твоя программа должна будет отжирать ~50МБ. Практически... Дай-ка угадаю! Конечно, она будет отжирать 100МБ!!!

ГЫ. Вот так вот тормозиллы и получаются.

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

А теперь сделай тест: пусть src будет строкой длиной 10кБ, needle пусть будет длиной 10Б и пусть оно встречается 500 раз в src. Сделай 10000 копий src и в каждой поудаляй needle.

а теперь давай не выдумывать глупые задачи, чтоб ими что-то аргументировать, а реальная задача, это например поднять файл XML в память и распарсить на месте, получить заголовок HTTP и распарсить на месте и т.д.

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

Я тебе это к тому, что тут пару страниц памяти сожрал сверх нужного, там сожрал...

LOL, а ничего, что твой вариант _всегда_ отжирает дополнительную память, а мой - только по желанию использующего? причем твой код явно выделяет память через malloc, а значит заюзать стек или пул для _экономии_ памяти, уменьшения фрагментации и оптимизации скорости работы не получится

wota ★★
()
Последнее исправление: wota (всего исправлений: 1)
Ответ на: комментарий от CARS
#include <java.h>
error: illegal character: \35
#include <java.h>
    String wordToRemove = args[1];
    String result = target.replace(wordToRemoce, "");

wordToRemove
wordToRemoce

Что-то ваша джава совсем не годная

И вообще

#!/usr/bin/env perl

print join '', split($ARGV[0], join(' ', @ARGV));

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

То же самое на mac os x 10.9, gcc-4.8.1

int main() {
  char teststring[] = "длинная строка, в которой строка - текст, который строка удалить надо строка вот";
  int i = 0;

  for( ; i < 10000000 ; ++i )
    {
      char buf[ 256 ];
      strcpy( buf, teststring );
      //      nokachi(buf, "строка" );

      //            beastie(buf, "строка" );
      //            wota(buf, "строка" );
      //            qulinxao(buf, "строка" );
            eddy(buf, "строка" );

    }
  return 0;
}

$ gcc -O2 remove_string.c
$ time ./a.out # nokachi

real	0m3.778s
user	0m3.208s
sys	0m0.547s
$ gcc -O2 remove_string.c
$ time ./a.out # beastie

real	0m4.951s
user	0m4.398s
sys	0m0.539s
$ gcc -O2 remove_string.c
$ time ./a.out # wota

real	0m3.387s
user	0m3.380s
sys	0m0.004s
$ gcc -O2 remove_string.c
$ time ./a.out # qulinxao

real	0m15.322s
user	0m15.286s
sys	0m0.011s
$ gcc -O2 remove_string.c
$ time ./a.out # eddy

real	0m4.951s
user	0m4.541s
sys	0m0.399s

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

твой вариант _всегда_ отжирает дополнительную память, а мой - только по желанию использующего?

посмотри внимательно: возвращается ровно столько, сколько надо.

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

Ты модифицируешь оригинал

Это вроди как начальное условие

и у тебя перерасход памяти.

где?

// а в действительности проблема, как заметил tailgunner, там надо было использовать strstr

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

посмотри внимательно: возвращается ровно столько, сколько надо.

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

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

а в действительности проблема, как заметил tailgunner, там надо было использовать strstr

вариант nokachi вроде как без strstr, а быстрее варианта beastie, да и опять же - ТС предлагал написать простой вариант, а не быстрый

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

читай вдумчиво, пока до тебя не дойдет

напиши это у себя на мониторе

П.С. зря я тебя сегодня разигнорил, отправлю-ка обратно...

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

А разве вариант beastie рабочий? Он ведь и «debug=debug» удалит целиком, да ещё и для «blahdebugblah 123» половину удалит до конца, еще и пробел с собой заберёт.

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

А где формальное описание задачи-то? Есть чувство, что каждый решал свою.

aedeph_ ★★
()

Мне таки стало очень интерессно! ☺

Кто там хотел сравнение? Встречайте: https://github.com/dim13/lor-contest

Код взян AS IS из этого треда. К не которым пришлось добавить враппер.

А теперь самое интерессное!

Результаты:

         beastie   pass   clobbes input                        116.58 ms
         Eddy_Em   pass                    has memory leaks    161.09 ms
          Gvidon   pass   clobbes input                        772.75 ms
    KennyMinigun   pass   clobbes input                        138.94 ms
      nokachi #1  fails                    has memory leaks    144.25 ms
      nokachi #2   pass                    has memory leaks    141.75 ms
        qulinxao   pass   clobbes input                        159.81 ms
   true_admin #1   pass                    has memory leaks    128.26 ms
   true_admin #2   pass                    has memory leaks    877.97 ms
            wota   pass   clobbes input                        482.95 ms

Discuss!

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

Наверно надо было бы написать «has potential memory leaks» — в теле используестся аллокация памяти без особождения. (Освобождение на совести вызывающего.)

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

А, ты про это. Мне кажется это вполне логичным подходом.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от beastie

Я не про интерес, я про формальное описание задачи. Где оно? Удивительное для меня поведения твоего решения здесь. Это баг, фича? Что означает колонка «pass» в таком случае?

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

У нокачи же. Правда его можно немного улучшить.

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

Обгрызание пробела это тоже фича? Вообще, твой вариант неэквивалентен ни одному из вариантов нокачи, какой нахрен pass. Ты что вообще мерил?

aedeph_ ★★
()
Ответ на: Мне таки стало очень интерессно! ☺ от beastie

ну и мой второй тогда добавь:

конкурс по си (комментарий)

раз qulinxao вариант есть, еще стоит сравнить по объему кода, правда там конечно стиль разный, так что стоит прогнать indent сначала

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

Добавил.

         beastie   pass   clobber input                              125.59 ms
         Eddy_Em   pass                    potential memory leaks    143.57 ms
          Gvidon   pass   clobber input                              730.35 ms
    KennyMinigun   pass   clobber input                              118.88 ms
      nokachi #1  fails                    potential memory leaks    117.61 ms
      nokachi #2   pass                    potential memory leaks    140.57 ms
        qulinxao   pass   clobber input                              158.64 ms
   true_admin #1   pass                    potential memory leaks    126.96 ms
   true_admin #2   pass                    potential memory leaks    885.50 ms
         wota #1   pass   clobber input                              464.18 ms
         wota #2   pass   clobber input                               88.53 ms

UPD: среднее за 5 проходов.

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

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

Я думаю, моё, например, сделает что-то не то со строкой «debuglevel=1».

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

debuglevel=1

Из всех вариантов только мой это правильно вырезает.

Если debug встречается внутри слова, например «vmlinuz-3.2.0-debug-amd64», то ниодин не справляется.

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

Целый тред крутых программистов с бенчмарками.

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

Не нужны мне жёсткие рамки, я хотел посмотреть на различные подходы и вспомнить сишечку. Я получил что хотел.

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

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