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)
Ответ на: комментарий от wota

tcc 0.9.26

Gros Relults
----

name             | func name        | passed           | gros time    | slower      
---              | ---              | ---              | ---          | ---         
wota             | remove_word      | ***************** |    358.19 ms |     17.85 % 
wota             | undebug_wota     | ****** *****   *  |    303.92 ms |      0.00 % 
qnikst           | undebugq uspace  | * *************** |    603.41 ms |     98.54 % 
qnikst           | undebugq2        | ***************** |    606.28 ms |     99.48 % 
qnikst           | undebugq3        | ***************** |    582.03 ms |     91.51 % 
qnikst           | undebugq         | * *************** |    598.94 ms |     97.07 % 
Carb             | debugdel         | * **** *****   *  |    374.06 ms |     23.08 % 
wota ★★
()
Ответ на: комментарий от wota

Пытайся дальше - на нормальном железе твоё поделие пока на уровне с моим +- 5%.

Выигрывает оно по причине наличия это стрчки:

if (_strcmp(str + 0) && (*(str + 5) == ' ' || *(str + 5) == '\0'))
		memset(str + 0, ' ', 5), str += 5;

Там выше кукарекали про strchr() - вот результат с моей strchr() на 64битных интах: http://pastebin.com/JNSijpUu

Пытайся дальше - пока слишком слабо. Я пока слишком занят - у тебя есть время.

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

Выкати её код - мне лень копатся.

Покачто strchr() сливает моей:

typedef char v8 __attribute__((__vector_size__(8)));
uint64_t create_mask(char c) {
  return (uint64_t)(v8){c, c, c, c, c, c, c, c};
}
char * _strchr64(char * data, int c) {
  uint64_t * str = (uint64_t *)data;
  uint64_t null = create_mask('\0'), needl = create_mask(c);
  uint64_t a = create_mask(0x7f), b = create_mask(0x80);
  uint64_t needl_mask = 0, null_mask = 0;
  do {
    needl_mask = (~((*str ^ needl) + a) & b);
    null_mask = (~((*str ^ null) + a) & b);
    ++str;
  } while(!needl_mask & !null_mask);
  if(!needl_mask) return NULL;
  return (((char *)(str - 1)) + (__bsfq(needl_mask) >> 3));
}

Неужели илитней моей? Мне прям интересно на что эти бомжи способны. Выкати её код - так уж и быть я для обоссу твою strchrnull().

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

Пытайся дальше - на нормальном железе твоё поделие пока на уровне с моим +- 5%.

а на «ненормальном» (старенький 2600K, да и у ТС вроде как) мое поделие быстрее твоего, кроме того мое умеет удалять не только «debug», так что это ты пока в роли догоняющего, пытайся дальше (с)

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

Рили, это уже называется «не толкьо дебуг» - ок.

if (p - s == 5 && *((int *)s) == 0x75626564 && s[4] == 'g')

strremove и remove_word сливает в говно. А ну да, тыж там даже tcc подпряг. Я конечно рад, что в тебе проснулись зачатки совести и ты решил улучшить свою идею, но всё же. Яж там выше кинул strchr(). Вперёд - моё уже давно быстрее.

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

У меня в на харденед профиле такая разница.

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

Ну дак вперёд - добавляй мою strchr(). Ты настолько глупый, что ты не понимаешь - я с тобою не сорвенуюсь. Я всё надеюсь, что ты перестанешь гнуть свои жалкие понты и будешь вести себя как человек. Я даже буду рад, если ты меня победишь.

Зачем ты так себя ведёшь? Ты хочешь доказать пацанам, что ты круче Царя? Доказывай - я тебе помогу, но с твоим подходом ты так ничего и не добьёшься. Ты реально не понимаешь, что если ты будешь лучше Царя - это будет эпик вин для меня. Всё моё недовольство миром - это отсутвие на лоре пацанов круче царя - будеь - я буду рад. Я хочу братьев по скиллу, мне не интересно побиждать бомжей.

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

На тебе ещё наподумать:

typedef char v8 __attribute__((__vector_size__(8)));
typedef enum {WITH_SPACE, WITHOUT_SPACE} mask_type_t;
inline char * cmp_and_replace(char * str, mask_type_t type) { 
  uint64_t debug_mask = (uint64_t)((v8){(type == WITH_SPACE) ? ' ' - ' ' : 0, 'd' - ' ', 'e' - ' ', 'b' - ' ', 'u' - ' ', 'g' - ' ', 0, 0});
  uint64_t needl_mask = (uint64_t)((v8){(type == WITH_SPACE) ? ' ' : 0, ' ', ' ', ' ', ' ', ' ', 0, 0});
  uint64_t drop_mask = (uint64_t)((v8){(type == WITH_SPACE) ? 0xff : 0, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0});
  uint64_t t = *((uint64_t *)str);
  if(((t ^= debug_mask) & drop_mask) == needl_mask) *((uint64_t *)(str + 0)) = t, str += 5;
  return ++str;
}

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

Скопируй и сравни с моей, а потом мы подумаем как же обоссать глибц. Почему вы думаете, что в этом мире есть что-то идеальное - нет, функции глибц куски говна.

Фейлов у глибц масса: latency у той же strstr()::sse4.2 раз в 10больше, чем у strchr()::<sse4, причем по производительности они примерно равны. С этим была байда, что на core2 replace работал раз в 10быстрее, чем на хасвеле по причине того, что там средний поиск был 3-5байт.

anonymous
()

Привет. Код не удовлетворяет условиям задачи (не для произвольной строки, а только для debug, и не на Си, а на плюсах), но все-равно оставлю его здесь:

#include <stdio.h>
#include <memory>
#include <ctype.h>

char* removeDebug(char* str, int offset) {
  char* ptr = str + 5;
  while(
       (ptr[-5] || !(ptr -= 5))
    && (ptr[-4] || !(ptr -= 4))
    && (ptr[-3] || !(ptr -= 3))
    && (ptr[-2] || !(ptr -= 2))
    && (ptr[-1] || !(ptr -= 1))) {
    if (!isalpha(ptr[0])
      && ptr[-1] == 'g'
      && ptr[-2] == 'u'
      && ptr[-3] == 'b'
      && ptr[-4] == 'e'
      && ptr[-5] == 'd') {
        if (!ptr[0]) {
          ptr -= 5;
          break;
        }
        int copySize = ptr - str - 5;
        char* result = removeDebug(ptr, copySize + offset);
        if (copySize) memmove(result + offset, str, copySize);
        return result;
    }
    else {
      switch(ptr[0]) {
        case 'g': ptr += 1; break;
        case 'u': ptr += 2; break;
        case 'b': ptr += 3; break;
        case 'e': ptr += 4; break;
        case 'd': ptr += 5; break;
        default: ptr += 6; break;
      }
    }
  }
  int newStrSize = ptr - str + offset;
  char* result = new char[newStrSize];
  int thisStrSize = ptr - str;
  memmove(result + offset, str, thisStrSize);
  result[offset + thisStrSize] = 0;
  return result;
}

int main() {
  char* original= (char*)"you debugging my debug with debug!";
  char* replaced = removeDebug(original, 0);
  printf("'%s'", replaced);
}

anonymous
()

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

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

place | name             | func name        | passed            | gros time    | slower
  --- | ---              | ---              | ---               | ---          | ---
    1 | qnikst           | undebugq2        | ***************** |     96.79 ms |      0.00 %
    2 | qnikst           | undebugq3        | ***************** |     98.22 ms |      1.47 %
    3 | wota             | remove_word      | ***************** |    113.86 ms |     17.64 %
    4 | beastie          | cutout           | ***************** |    127.67 ms |     31.90 %
    5 | anonymous        | anon_strcut      | ***************** |    138.32 ms |     42.91 %
    6 | puzan            | str_mask_str     | ***************** |    144.84 ms |     49.65 %
    7 | beastie          | undebug          | ***************** |    162.05 ms |     67.42 %
    8 | qulinxao         | wordstrings      | ***************** |    168.14 ms |     73.72 %
    9 | mix-mix          | strcut           | ***************** |    207.23 ms |    114.10 %
   10 | puzan            | str_drop_str     | ***************** |    224.81 ms |    132.26 %
   11 | beastie          | wipeout          | ***************** |    313.29 ms |    223.68 %
   12 | qnikst           | undebugq uspace  | * *************** |     97.77 ms |      1.01 %
   13 | qnikst           | undebugq         | * *************** |    106.10 ms |      9.62 %
   14 | beastie          | split            |   **** ********** |    388.87 ms |    301.77 %
   15 | anonymous        | anon_wipedebug   | ****** *****   *  |     70.17 ms |    -27.50 %
   16 | wota             | undebug_wota     | ****** *****   *  |     70.23 ms |    -27.45 %
   17 | Carb             | debugdel         | * **** *****   *  |     74.27 ms |    -23.26 %
   18 | nokachi          | remove           | ** *******   **   |    240.12 ms |    148.08 %
   19 | beastie          | cutout_orig      | ***   **    *** * |    153.37 ms |     58.45 %
   20 | KennyMinigun     | strdel           | ***   **    *** * |    166.07 ms |     71.58 %
   21 | anonymous        | strcut           | ***   **    *** * |    175.38 ms |     81.20 %
   22 | true_admin       | cut              | ***   **    *** * |    206.77 ms |    113.63 %
   23 | wota             | strremove        | ***   **    *** * |    704.76 ms |    628.14 %
   24 | Gvidon           | process          | ***   **    *** * |    857.14 ms |    785.56 %
   25 | true_admin       | cut2             | ***   **    *** * |   1507.19 ms |   1457.18 %
   26 | Eddy_Em          | delsubstr        |  **  * *    * * * |    298.53 ms |    208.43 %
   27 | nop              | nop              |   ****         ** |     36.51 ms |    -62.28 %
beastie ★★★★★
()
Ответ на: комментарий от beastie

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

Далее, завтра я напишу норм бенч - заменим твоё говно, которое выдаёт вот это:

testing    input "systemd.debug"
          needle "debug"
          expect "systemd.debug"
             nop .................... pass    10.02 ms
       strremove .................... fail    43.86 ms
     remove_word .................... pass    19.10 ms
    undebug_wota .................... pass    11.77 ms
        debugdel .................... pass    11.39 ms

Просто 850% оверхед на тест и это время он считает. Блин это такой фейспал, не смеши мои тапки, а?

Там в моём результате половина времени - говнистость твоего теста - это норма?

И да, что там у тебя за железо и конпелятор на котором ты это мериешь? Это должно быть в шапке твоей таблицы.

needle «debug=UUID=42debug5-6ee1-464c-bc41-debug42debug»

Что это за самодеятельность? Иди перечитай правила.

Нужно выпилить слово debug из исходной строки.
В случае неоднозначности формулировки задания результат интерпретируется в пользу участника.

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

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

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

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

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

2beastie:

if (strcmp(w, "debug") == 0)

вот взял и поломал :) там смысл был как раз в том, что сравнение указателей быстрое и это именно оптимизация для частного случая, а ты подставил тормозной strcmp

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

и таки вопрос он задал правильный - а на какой ОС, железе и компиляторе это все прогонялось, а то у меня для не для линукса вообще другой код гоняется, хотя лично я б его вообще выкинул

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

у меня на компе твой вариант выигрывает процентов на 10.

ну тут видно и так и будет - на разных ОС и железе по разному, так что на данный момент я б расставил бы места так:

1) анонимус с anon_wipedebug - очень красивое и быстрое решение
2) qnikst - самое быстрое (у ТС) универсальное решение
3) я с конкурс по си (комментарий) :) - быстрое и компактное решение

разве что убрал бы каст к int*:

void undebug_wota(char *s) {
    char *p = s;
    for (; *p; s = p + 1) {
        p = strchrnul(s, ' ');
        if (p - s == 5 && !memcmp(s, "debug", 5))
            memset(s, ' ', 5);
    }
}

для большей читабельности

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

да, согласен.

Кстати заметил, что у меня glibc с отладочными символами собран, попробую пересобрать и прогнать заново.

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

Ты там нашел strchr()? Ты обещал, вот тебе прийдётся пилить для своей байды свой strchr(), чтоб царю не слить. Выкатывай, авось придумаешь что-то вменяемое.

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

ты читать научись сначала, что я пишу. Я с царём не соревнуюсь, я решаю задачу в общем случае (любая строка по которой ищут).

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

Зачем вы его царем называете? Он же из-за этого еще больше зазнается.

Я вот первый раз прочитал слово «Carb» как «Краб». Вполне подходящее для него погоняло.

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

это он себя сам так называл, вот и приклеилось, все его сообщения сводились к «Я Царь, а ты лалка, <кусок бреда>. я тебя за траллил!!!».

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

на какой ОС, железе и компиляторе это все прогонялось

Последний тест гонялся на Squeeze/2.6.32-5-amd64 (gcc 4.4.5) Intel(R) Xeon(R) CPU E31220 @ 3.10GHz

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

Это просто «неправильный си»

еще как правильный ;) это оптимизация с расчетом на то, что компилятор соберет одинаковые константные строки в одну, правда все-равно она не сработает - у тебя используется char*, а не const char*

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

Кстати, ты так и будешь отмалчиватся? Зачем ты нарушил правила конкурса и впилил туда некорректыне правилам тесты?

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

Ты мне очень надоел своим бредом и у тебя по всем признакам острое воспаление buthurt'а. Но я тебе всё же отвечу.

Смотри внимательно. Здесь:

  • «debug» => «»
  • «debugfs» => «debugfs»
  • «debug=1» => «debug=1»
  • «debug systemd.debug» => " systemd.debug"
  • «debug 123 debug 456» => " 123 456"

Слово «debug» — это «placeholder». И соответственно это равнозначно:

  • «quiet» => «»
  • «quietfs» => «quietfs»
  • «quiet=1» => «quiet=1»
  • «quiet systemd.quiet» => " systemd.quiet"
  • «quiet 123 quiet 456» => " 123 456"

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

Твоё решение хоть и быстрое, но частное и не удовлетворяет общим условиям. Вот и весь сказ.

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

Ты мне очень надоел своим бредом и у тебя по всем признакам острое воспаление buthurt'а. Но я тебе всё же отвечу.

Я уже выше привел пруфцы галимости твоих тестов, я уже привел пруфцы того, что мне ничего не стоит выйграть это говно - суть не в этом - суть в тебе.

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

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

У тебя? У тебя.

Переходим по ссылки и читаем:

Нужно выпилить слово debug из исходной строки.

Конеретно - нужно выпилить слово: debug. Не ЛЮБОЕ СЛОВО, а конкретное слово.

В коде использовать только вот эти функции:

У тебя половина функций юзают функции, которых тут нет.

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

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

Даже, если бы тут было неоднозначность, которой тут нет - тя был бы всё ровно прав, ибо перечитай ещё раз.

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

Что, попа болит на троне сидеть?

Заметь, ты единственный из всех, кто принимал участие, разводишь тут такие сопли. Соревнуешься с кем-то, переживаешь, пытаешься что-то доказать с пеной у рта, ругаешься.

Пойми — это дружеское соревнование, обмен опытом и идеями.

Мой тест «нехороший»? Ну что ж, пиши свой, корректный, раз так сильно свербит. Ты ведь грозился? Ну так, где он, твой корректный бенчмарк? А... нету... времени нету, желания нету... всё ясно.

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

mingw epic fail

запилил а-ля perftest но под mingw (sorry - железка с linux сейчас ремонтируется), из тестов исключены :

  • варианты использующие strsep, за его отсутсвием в сборке
  • варианты с strstr - просто багуют, пока лень разбираться отчего (подозреваю, что при возврате NULL или «\0»)
  • некоторые дивные вещи типа Eddy_Em delsubstr - похоже перепахивают память наглухо

всего включены 15 функций и 27 тестов, все тесты проходят всего 4 функции; при сборке gcc 4.8.1 -O3 результаты в пределах погрешности измерений за лидерством anonymous anon_wipedebug; при -O0 лидер тот-же, прочие выстраиваются по длине кода.

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

типичный результат прогона, в виде «имя функция пройдено_тестов суммарное_время»

Gvidon process 	 15 0.062
KennyMinigun strdel 	 18 0.043
nokachi remove 	 23 0.221
qulinxao wordstrings 	 27 0.151
wota undebug_wota 	 15 0.029
anonymous anon_strcut 	 27 0.107
anonymous anon_wipedebug 	 27 0.080
puzan str_drop_str 	 12 0.150
puzan str_mask_str 	 27 0.111
qnikst undebugq uspace 	 18 0.064
qnikst undebugq2 	 26 0.090
qnikst undebugq3 	 26 0.089
qnikst undebugq 	 18 0.040
Carb debugdel 	 23 0.073
MKuznetsov undebugit2 	 27 0.138

MKuznetsov ★★★★★
()

Такое сойдет?

#include <stdio.h>
#include <string.h>
#include <stdlib.h>


int main(int argc, char ** argv)
{
  char * string; 
  char * needle;
  int len;
  char * buf;
  int i = 0;

  if (argv[1] == NULL) {
    fprintf (stderr, "Usage: %s string needle\n", argv[0]);
    return 1;
  }

  string = strdup (argv[1]);
  needle = strdup (argv[2]);
  len = strlen (needle);
  buf = malloc (strlen(string) + 1);
  for(;;) {
    if (!strncmp (string, needle, len)) {
      string += len;
      continue;
    }    
    buf[i] = string[0];
    i++;
    if (string[0] == '\0') break;
    string++;
  }
  printf ("%s\n",buf);
  return 0;
}

$ gcc str2.c
$ ./a.out "root=/dev/mmcblk0p1 ro debug quiet debug splash ololo test debug" " debug"
root=/dev/mmcblk0p1 ro quiet splash ololo test

Вроде работает.

Extraterrestrial ★★★★★
()
Последнее исправление: Extraterrestrial (всего исправлений: 1)

Вы бы хоть тестов нормальных добавили.

«it is nice to count 1 2 3 4 5 debug 6 7 debus 8 debux 9»

«oh my god debug debuu debus debup debul debuu»

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

А то, что некоторые из «быстрых» решений на подобных тестах будут работать медленно.

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

$ ./a.out debugbug debug
bug

конкурс по вырезанию произвольного слова из строки

ну а что тут не так? Строка - «debugbug» (первый аргумент), произвольное слово - «debug» (второй аргумент). Убери из этой строки слово «debug» и получится как раз то, что выдала программа.

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

ты путаешь слово с подстрокой.

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