ГНКОД
От: okman Беларусь https://searchinform.ru/
Дата: 17.09.11 11:28
Оценка: +1 -2
Вот я часто вижу тут: "говнокод, говнокод"...
А ведь говнокод имеет право на жизнь, и причем нехилое такое право.

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

Тем не менее, библиотеки успешно держатся на плаву уже несколько лет и,
что самое важное, умеют выжимать эти последние 3-5%, когда остальные пасуют.

Лично для себя я давно открыл разделение кода на библиотечный и клиентский (или интерфейсный).
Все, что внутри библиотечного кода, клиентов интересовать не должно, это черный ящик.
То, что он доверху набит дерьмом, клиента не заботит. Важнее то, что ящик сшибает
конкурентов и делает работу на пять с плюсом, а то, как он написан — забота авторов.

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

Готов провести линию и дальше — есть "библиотечные" языки, а есть "клиентские".
Например, C — типичный "библиотечник", а C++/.NET/Java — скорее для клиентского кода.

Отлично понимаю, что все это — открытие Америки, просто довольно часто вижу,
как тут на RSDN кто-то выкладывает код, и его (код) тут же начинают поливать грязью за
"смешивание в presentation layer", за "невнятное именование", за "использование A там,
где логичнее было бы использовать B", и так далее в том же духе.

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

P.S. Отвечать быстро не смогу, так как занят написанием кода (красивого и быстрого).
Но троллинг и минусятничанье приветствуются.
Re: ГНКОД
От: 0x7be СССР  
Дата: 17.09.11 11:40
Оценка: +2
Здравствуйте, okman, Вы писали:

O>Вот я часто вижу тут: "говнокод, говнокод"...

O>А ведь говнокод имеет право на жизнь, и причем нехилое такое право.
Говнокод безусловно имеет право на жизнь... если его не мне сопровождать

O>А задумайтесь — вдруг от эффективности этой библиотеки будет зависеть жизнь людей.

Действительно, ошибки в запутанном коде — это как раз то, что нужно для критичных приложений
Re: ГНКОД
От: Abyx Россия  
Дата: 17.09.11 12:05
Оценка:
Здравствуйте, okman, Вы писали:

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

O>что самое важное, умеют выжимать эти последние 3-5%, когда остальные пасуют.

говнокод — это не тот код который не работает, или который работает плохо,
этот тот код который сложно читать\поддерживать.
In Zen We Trust
Re[2]: ГНКОД
От: okman Беларусь https://searchinform.ru/
Дата: 17.09.11 12:28
Оценка:
Здравствуйте, Abyx, Вы писали:

A>говнокод — это не тот код который не работает, или который работает плохо,

A>этот тот код который сложно читать\поддерживать.

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

А теперь вопрос — говнокод ли это ?

  для разминки
for (;;) {
        if ((low % 6) == 0) printf("\n        ");
        printf("{%u,%u,%d}", lenfix[low].op, lenfix[low].bits,
               lenfix[low].val);
        if (++low == size) break;
        putchar(',');
    }
    puts("\n    };");
    size = 1U << 5;
    printf("\n    static const code distfix[%u] = {", size);
    low = 0;
    for (;;) {
        if ((low % 5) == 0) printf("\n        ");
        printf("{%u,%u,%d}", distfix[low].op, distfix[low].bits,
               distfix[low].val);
        if (++low == size) break;
        putchar(',');
    }
    puts("\n    };");


  вариации switch-case
    case EDOM: return make_error_condition( argument_out_of_domain );
    case EEXIST: return make_error_condition( file_exists );
    case EFAULT: return make_error_condition( bad_address );
    case EFBIG: return make_error_condition( file_too_large );
    case EHOSTUNREACH: return make_error_condition( host_unreachable );
    case EIDRM: return make_error_condition( identifier_removed );
    case EILSEQ: return make_error_condition( illegal_byte_sequence );
    case EINPROGRESS: return make_error_condition( operation_in_progress );
    case EINTR: return make_error_condition( interrupted );
    case EINVAL: return make_error_condition( invalid_argument );
    case EIO: return make_error_condition( io_error );
    case EISCONN: return make_error_condition( already_connected );
    case EISDIR: return make_error_condition( is_a_directory );
    case ELOOP: return make_error_condition( too_many_symbolic_link_levels );
    case EMFILE: return make_error_condition( too_many_files_open );
    case EMLINK: return make_error_condition( too_many_links );
    case EMSGSIZE: return make_error_condition( message_size );
    case ENAMETOOLONG: return make_error_condition( filename_too_long );
    case ENETDOWN: return make_error_condition( network_down );
    case ENETRESET: return make_error_condition( network_reset );
    case ENETUNREACH: return make_error_condition( network_unreachable );
    case ENFILE: return make_error_condition( too_many_files_open_in_system );
    case ENOBUFS: return make_error_condition( no_buffer_space );
    case ENODATA: return make_error_condition( no_message_available );
    case ENODEV: return make_error_condition( no_such_device );
    case ENOENT: return make_error_condition( no_such_file_or_directory );
    case ENOEXEC: return make_error_condition( executable_format_error );
    case ENOLCK: return make_error_condition( no_lock_available );
    case ENOLINK: return make_error_condition( no_link );
    case ENOMEM: return make_error_condition( not_enough_memory );
    case ENOMSG: return make_error_condition( no_message );
    case ENOPROTOOPT: return make_error_condition( no_protocol_option );
    case ENOSPC: return make_error_condition( no_space_on_device );
    case ENOSR: return make_error_condition( no_stream_resources );
    case ENOSTR: return make_error_condition( not_a_stream );
    case ENOSYS: return make_error_condition( function_not_supported );


  мое любимое
    m_rounds = (keylen >= 24) ? 4 : 3;
    unsigned int kslen = (8 * m_rounds + 2);
    m_key.New(kslen*2);
    word32 *ks32 = m_key.data();
    int m=0, a=0;
    if (!IsForwardTransformation())
        m = -1, a = kslen-1;

    word32 kl0, kl1, kl2, kl3;
    GetBlock<word32, BigEndian> getBlock(key);
    getBlock(kl0)(kl1)(kl2)(kl3);
    word32 k0=kl0, k1=kl1, k2=kl2, k3=kl3;

#define CALC_ADDR2(base, i, j)    ((byte *)(base)+8*(i)+4*(j)+((-16*(i))&m))
#define CALC_ADDR(base, i)    CALC_ADDR2(base, i, 0)

#if 1
    word64 kwl, kwr;
    ks32 += 2*a;
#define PREPARE_KS_ROUNDS            \
    kwl = (word64(k0) << 32) | k1;    \
    kwr = (word64(k2) << 32) | k3
#define KS_ROUND_0(i)                            \
    *(word64*)CALC_ADDR(ks32, i+EFI(0)) = kwl;    \
    *(word64*)CALC_ADDR(ks32, i+EFI(1)) = kwr
#define KS_ROUND(i, r, which)                                                                                        \
    if (which & (1<<int(r<64))) *(word64*)CALC_ADDR(ks32, i+EFI(r<64)) = (kwr << (r%64)) | (kwl >> (64 - (r%64)));    \
    if (which & (1<<int(r>64))) *(word64*)CALC_ADDR(ks32, i+EFI(r>64)) = (kwl << (r%64)) | (kwr >> (64 - (r%64)))
#else
    __m128i kw, kw2;
    __m128i *ks128 = (__m128i *)ks32+a/2;
    ks32 += 2*a;
#define PREPARE_KS_ROUNDS                                                    \
    kw = _mm_set_epi32(k0, k1, k2, k3);                                        \
    if (m) kw2 = kw, kw = _mm_shuffle_epi32(kw, _MM_SHUFFLE(1, 0, 3, 2));    \
    else kw2 = _mm_shuffle_epi32(kw, _MM_SHUFFLE(1, 0, 3, 2))
#define KS_ROUND_0(i)                                        \
    _mm_store_si128((__m128i *)CALC_ADDR(ks128, i), kw)
#define KS_ROUND(i, r, which)    {                                                                                \
    __m128i temp;                                                                                                \
    if (r<64 && (which!=1 || m)) temp = _mm_or_si128(_mm_slli_epi64(kw, r%64), _mm_srli_epi64(kw2, 64-r%64));    \
    else temp = _mm_or_si128(_mm_slli_epi64(kw2, r%64), _mm_srli_epi64(kw, 64-r%64));                            \
    if (which & 2) _mm_store_si128((__m128i *)CALC_ADDR(ks128, i), temp);                                        \
    else _mm_storel_epi64((__m128i*)CALC_ADDR(ks32, i+EFI(0)), temp);                                            \
    }
Re: ГНКОД
От: microuser  
Дата: 17.09.11 12:44
Оценка:
Автор, наверное, смотрел код после работы обфускатора
Re[3]: ГНКОД
От: Abyx Россия  
Дата: 17.09.11 12:51
Оценка:
Здравствуйте, okman, Вы писали:

O>Приведу примеры, взятые из нескольких популярных библиотек.

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

O>А теперь вопрос — говнокод ли это ?


O>[... 3 примера]


да, да, и да.
в 1м и 3м случае потому что человек впервые видя этот код не может сказать что и как этот код делает
во 2м случае это не то чтобы "говнокод", он просто неоптимален и потребует много усилий чтобы переименовать make_error_condition
In Zen We Trust
Re: ГНКОД
От: Ночной Смотрящий Россия  
Дата: 17.09.11 13:09
Оценка:
Здравствуйте, okman, Вы писали:

O>А задумайтесь — вдруг от эффективности этой библиотеки будет зависеть жизнь людей.


Ага, вдруг она на АЭС применятся будет.
Жизнь людей обычно не от 3-5% перформанса зависит, а от наличия багов. В каком коде багов будет больше, а?

O>Что, красивый код важнее тех плюс трех-пяти процентов, которые иногда можно получить с

O>помощью некрасивого решения типа goto ?

В 99.99% — да. Хотя бы потому что в красивом коде очень часто легче сделать не выжимание битов, а алгоритмическую оптимизацию, дающую плюс 30-50%.
Re[3]: ГНКОД
От: Ночной Смотрящий Россия  
Дата: 17.09.11 13:11
Оценка:
Здравствуйте, okman, Вы писали:

O>А теперь вопрос — говнокод ли это ?

O>для разминки

Нет.

O>вариации switch-case


Нет. Хотя такое лучше генераторами делать, если в большом объеме.

O>мое любимое


А это действительно говонокод.
Re[3]: ГНКОД
От: 0x7be СССР  
Дата: 17.09.11 13:18
Оценка:
Здравствуйте, okman, Вы писали:

O>А теперь вопрос — говнокод ли это ?

1-ый и 3-ий безусловно.
2-ой — терпимо.
Re: ГНКОД
От: dilmah США  
Дата: 17.09.11 14:22
Оценка: :))) :)
> ГНКОД

офф: предлагаю альтернативный эвфемизм: ГМОКОД -- код который пишут генетически модифицированные организмы
Re: ГНКОД
От: elmal  
Дата: 17.09.11 16:28
Оценка: +1
Здравствуйте, okman, Вы писали:

O>Вот я часто вижу тут: "говнокод, говнокод"...

O>А ведь говнокод имеет право на жизнь, и причем нехилое такое право.
Смотря что понимать под говнокодом. Прикол в том, что цели клиентского кода и библиотечного различны. Клиентский — требования к скорости чаще всего не важны, а требуется максимальная понятность, поддерживаемость и расширяемость. А к библиотечному критерии другие — это не должно тормозить и это должно работать на чем угодно, максимально используя ресурсы. Понятность в библиотечном коде на 10-м месте, туда все равно никто не полезет. Соответственно если в коде библиотеки сам черт ногу сломит, но работает максимально быстро — это не говнокод. Главное чтоб багов не было.
Re[2]: ГНКОД
От: 0x7be СССР  
Дата: 17.09.11 17:06
Оценка: +2
Здравствуйте, elmal, Вы писали:

E>Смотря что понимать под говнокодом. Прикол в том, что цели клиентского кода и библиотечного различны. Клиентский — требования к скорости чаще всего не важны, а требуется максимальная понятность, поддерживаемость и расширяемость. А к библиотечному критерии другие — это не должно тормозить и это должно работать на чем угодно, максимально используя ресурсы. Понятность в библиотечном коде на 10-м месте, туда все равно никто не полезет. Соответственно если в коде библиотеки сам черт ногу сломит, но работает максимально быстро — это не говнокод. Главное чтоб багов не было.

А сопровождать эти библиотеки кто-то будет или нет?
Качество кода — это такая шутка, она не для пользователя продукта (библиотеки), а для тех, кто её пишет и поддерживает.
Re[2]: ГНКОД
От: Ночной Смотрящий Россия  
Дата: 17.09.11 19:15
Оценка:
Здравствуйте, elmal, Вы писали:

E>Смотря что понимать под говнокодом.


А что, есть в этом вопросе разночтения?

E> Прикол в том, что цели клиентского кода и библиотечного различны.


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

E> Клиентский — требования к скорости чаще всего не важны


Обоснуй.

E>а требуется максимальная понятность, поддерживаемость и расширяемость


А в библиотечном коде не требуется?

E>А к библиотечному критерии другие — это не должно тормозить


Это всегда главный критерий качества библиотечного кода? И как определить, тормозит он или уже достаточно быстродействия? Есть какие то нормативы? Или надо потратить не менее ХХХ баксов на тюнинг YYY строчек библиотечного кода?

E> и это должно работать на чем угодно


В каком смысле?

E>максимально используя ресурсы


Какие и зачем?

E>Понятность в библиотечном коде на 10-м месте, туда все равно никто не полезет


Даже автор библиотеки? Ты часто такой код сам пишешь?

E>Соответственно если в коде библиотеки сам черт ногу сломит


Во всех твоих библиотеках черт ногу сломит?

E>Главное чтоб багов не было.


Как считаешь, количество багов зависит от чистоты кода?
Re[2]: ГНКОД
От: Banned by IT  
Дата: 17.09.11 20:43
Оценка:
Здравствуйте, elmal, Вы писали:

E>Соответственно если в коде библиотеки сам черт ногу сломит, но работает максимально быстро — это не говнокод.

Дело в том, что даже битовыжималку можно написать так, чтоб она достаточно легко читалась.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[3]: ГНКОД
От: Banned by IT  
Дата: 17.09.11 20:43
Оценка:
Здравствуйте, okman, Вы писали:

O>А теперь вопрос — говнокод ли это ?

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

O>
  для разминки

Не говнокод, небольшая стилистическая правка улучшит читабельность.

O>
  вариации switch-case

Как минимум форматирование "табличкой" сильно улучшит читабельность.

O>
  мое любимое

Хехе. Ну, оформление исключительно отвратительное.
Но тем не менее даже это можно привести в легкочитаемый вид, ничего не сломав в производительности алгоритма.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[3]: ГНКОД
От: TarasKo Голландия  
Дата: 18.09.11 07:38
Оценка: +3 -1
Переименовать переменные, написать комментарии, дать функциям осмысленные имена. Код от этого не станет медленнее, но зато потеряет приставку "говно"

Здравствуйте, okman, Вы писали:

O>Здравствуйте, Abyx, Вы писали:


A>>говнокод — это не тот код который не работает, или который работает плохо,

A>>этот тот код который сложно читать\поддерживать.

O>Приведу примеры, взятые из нескольких популярных библиотек.

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

O>А теперь вопрос — говнокод ли это ?


O>
  для разминки
O>
O>for (;;) {
O>        if ((low % 6) == 0) printf("\n        ");
O>        printf("{%u,%u,%d}", lenfix[low].op, lenfix[low].bits,
O>               lenfix[low].val);
O>        if (++low == size) break;
O>        putchar(',');
O>    }
O>    puts("\n    };");
O>    size = 1U << 5;
O>    printf("\n    static const code distfix[%u] = {", size);
O>    low = 0;
O>    for (;;) {
O>        if ((low % 5) == 0) printf("\n        ");
O>        printf("{%u,%u,%d}", distfix[low].op, distfix[low].bits,
O>               distfix[low].val);
O>        if (++low == size) break;
O>        putchar(',');
O>    }
O>    puts("\n    };"); 
O>



O>
  вариации switch-case
O>
O>    case EDOM: return make_error_condition( argument_out_of_domain );
O>    case EEXIST: return make_error_condition( file_exists );
O>    case EFAULT: return make_error_condition( bad_address );
O>    case EFBIG: return make_error_condition( file_too_large );
O>    case EHOSTUNREACH: return make_error_condition( host_unreachable );
O>    case EIDRM: return make_error_condition( identifier_removed );
O>    case EILSEQ: return make_error_condition( illegal_byte_sequence );
O>    case EINPROGRESS: return make_error_condition( operation_in_progress );
O>    case EINTR: return make_error_condition( interrupted );
O>    case EINVAL: return make_error_condition( invalid_argument );
O>    case EIO: return make_error_condition( io_error );
O>    case EISCONN: return make_error_condition( already_connected );
O>    case EISDIR: return make_error_condition( is_a_directory );
O>    case ELOOP: return make_error_condition( too_many_symbolic_link_levels );
O>    case EMFILE: return make_error_condition( too_many_files_open );
O>    case EMLINK: return make_error_condition( too_many_links );
O>    case EMSGSIZE: return make_error_condition( message_size );
O>    case ENAMETOOLONG: return make_error_condition( filename_too_long );
O>    case ENETDOWN: return make_error_condition( network_down );
O>    case ENETRESET: return make_error_condition( network_reset );
O>    case ENETUNREACH: return make_error_condition( network_unreachable );
O>    case ENFILE: return make_error_condition( too_many_files_open_in_system );
O>    case ENOBUFS: return make_error_condition( no_buffer_space );
O>    case ENODATA: return make_error_condition( no_message_available );
O>    case ENODEV: return make_error_condition( no_such_device );
O>    case ENOENT: return make_error_condition( no_such_file_or_directory );
O>    case ENOEXEC: return make_error_condition( executable_format_error );
O>    case ENOLCK: return make_error_condition( no_lock_available );
O>    case ENOLINK: return make_error_condition( no_link );
O>    case ENOMEM: return make_error_condition( not_enough_memory );
O>    case ENOMSG: return make_error_condition( no_message );
O>    case ENOPROTOOPT: return make_error_condition( no_protocol_option );
O>    case ENOSPC: return make_error_condition( no_space_on_device );
O>    case ENOSR: return make_error_condition( no_stream_resources );
O>    case ENOSTR: return make_error_condition( not_a_stream );
O>    case ENOSYS: return make_error_condition( function_not_supported );
O>



O>
  мое любимое
O>
O>    m_rounds = (keylen >= 24) ? 4 : 3;
O>    unsigned int kslen = (8 * m_rounds + 2);
O>    m_key.New(kslen*2);
O>    word32 *ks32 = m_key.data();
O>    int m=0, a=0;
O>    if (!IsForwardTransformation())
O>        m = -1, a = kslen-1;

O>    word32 kl0, kl1, kl2, kl3;
O>    GetBlock<word32, BigEndian> getBlock(key);
O>    getBlock(kl0)(kl1)(kl2)(kl3);
O>    word32 k0=kl0, k1=kl1, k2=kl2, k3=kl3;

O>#define CALC_ADDR2(base, i, j)    ((byte *)(base)+8*(i)+4*(j)+((-16*(i))&m))
O>#define CALC_ADDR(base, i)    CALC_ADDR2(base, i, 0)

O>#if 1
O>    word64 kwl, kwr;
O>    ks32 += 2*a;
O>#define PREPARE_KS_ROUNDS            \
O>    kwl = (word64(k0) << 32) | k1;    \
O>    kwr = (word64(k2) << 32) | k3
O>#define KS_ROUND_0(i)                            \
O>    *(word64*)CALC_ADDR(ks32, i+EFI(0)) = kwl;    \
O>    *(word64*)CALC_ADDR(ks32, i+EFI(1)) = kwr
O>#define KS_ROUND(i, r, which)                                                                                        \
O>    if (which & (1<<int(r<64))) *(word64*)CALC_ADDR(ks32, i+EFI(r<64)) = (kwr << (r%64)) | (kwl >> (64 - (r%64)));    \
O>    if (which & (1<<int(r>64))) *(word64*)CALC_ADDR(ks32, i+EFI(r>64)) = (kwl << (r%64)) | (kwr >> (64 - (r%64)))
O>#else
O>    __m128i kw, kw2;
O>    __m128i *ks128 = (__m128i *)ks32+a/2;
O>    ks32 += 2*a;
O>#define PREPARE_KS_ROUNDS                                                    \
O>    kw = _mm_set_epi32(k0, k1, k2, k3);                                        \
O>    if (m) kw2 = kw, kw = _mm_shuffle_epi32(kw, _MM_SHUFFLE(1, 0, 3, 2));    \
O>    else kw2 = _mm_shuffle_epi32(kw, _MM_SHUFFLE(1, 0, 3, 2))
O>#define KS_ROUND_0(i)                                        \
O>    _mm_store_si128((__m128i *)CALC_ADDR(ks128, i), kw)
O>#define KS_ROUND(i, r, which)    {                                                                                \
O>    __m128i temp;                                                                                                \
O>    if (r<64 && (which!=1 || m)) temp = _mm_or_si128(_mm_slli_epi64(kw, r%64), _mm_srli_epi64(kw2, 64-r%64));    \
O>    else temp = _mm_or_si128(_mm_slli_epi64(kw2, r%64), _mm_srli_epi64(kw, 64-r%64));                            \
O>    if (which & 2) _mm_store_si128((__m128i *)CALC_ADDR(ks128, i), temp);                                        \
O>    else _mm_storel_epi64((__m128i*)CALC_ADDR(ks32, i+EFI(0)), temp);                                            \
O>    }
O>

Re[3]: ГНКОД
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 20.09.11 08:45
Оценка: :)
Здравствуйте, okman, Вы писали:

O>А теперь вопрос — говнокод ли это ?


Да, Да, Да.
Re: ГНКОД
От: borisman3 Канада http://paskoboris.blogspot.com/
Дата: 17.10.11 04:04
Оценка:
O>Вот я часто вижу тут: "говнокод, говнокод"...
O>А ведь говнокод имеет право на жизнь, и причем нехилое такое право.

Поясняю для прессы.

Для того чтобы писать красивый код, надо иметь мозг и опыт на пару порядков превышающий уровень задачи. Так товарищ Кнут показывает нам пример литературного программирования на примере задачи о 8ми ферзях.
Я могу писать суперкрасивый литературный код в стиле test-first при условиях что:
а) Я сравнительно трезв
бе) Это какой-нибудь идиотский парсер даты
це) Когда мои временные ресурсы (почти) не ограничены
де) Я хочу показать что я хуже многих и тоже могу много (выпивать).

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

Затем этот код ревьюится сначала мной (переписывается) затем товарищем (переписывается), затем каллевтивом (переписывается, подчас даже не мной). И только потом-потом-потом он приобретает некую даже я бы сказал элегантность.

O>Я заглядывал под капот некоторым библиотекам, которые позиционируются как

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

Бывает так что все эти ваши соображения о красоте погон идут лесом и на передний план выступают совсем иные требования. Самое типичное — скорость. Еще типичное — интеграция (тут нужно сделать не очень красиво с точки зрения модуля, но красиво с точки зрения всей системы/архитектуры). Менее типичное — сопровождаемость. Как это ни странно, далеко не всегда очевидный и логичный код более сопровождаем.

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

O>что самое важное, умеют выжимать эти последние 3-5%, когда остальные пасуют.

Выжимка 3-5% в моих задачах (кластерные вычисления) редко играет роль. Вот, положим 50% это да.

O>Лично для себя я давно открыл разделение кода на библиотечный и клиентский (или интерфейсный).

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

Это примитивисткий взгляд. Очень часто приходится-таки копаться в кишках библиотек, ибо автор совершенно не представлял, что его библиотеку будут иметь в таких положениях. Хорошо, если автор приложил усилие и сделал код худо-бедно читаемым. Не сделал — ну что-ж, вина тут не автора, это мы пользуем библиотеку не в той позе.

O>Клиентский код, напротив, обязан быть предельно прозрачным и аккуратным, с разделением на

O>всякие там абстракции, слои, и т.д.

Где клиент, а где библиотека ? Одно переходит в другое и обратно.

O>Готов провести линию и дальше — есть "библиотечные" языки, а есть "клиентские".

O>Например, C — типичный "библиотечник", а C++/.NET/Java — скорее для клиентского кода.

Мысль ясна, но Java в последнее время становится в позицию библиотечного языка для Scala, Groovy, Jython. Все тут зыбко.

O>Отлично понимаю, что все это — открытие Америки, просто довольно часто вижу,

O>как тут на RSDN кто-то выкладывает код, и его (код) тут же начинают поливать грязью за
O>"смешивание в presentation layer", за "невнятное именование", за "использование A там,
O>где логичнее было бы использовать B", и так далее в том же духе.

Разные люди, разные мнения. Прислушиваться можно, но в голову не берите. Те самые плюсы, которые вы внесете по советам с RSDN будут восприняты вашими коллегами (по проекту) как явные минусы. Лучше советоваться с коллегами. Все субъективно, и я с радостью изуродую свой код если мои коллеги — уроды.

O>А задумайтесь — вдруг от эффективности этой библиотеки будет зависеть жизнь людей.

O>Что, красивый код важнее тех плюс трех-пяти процентов, которые иногда можно получить с
O>помощью некрасивого решения типа goto ?

Бросьте. Никогда нам с Вами не писать кода, от которого будет зависеть чья-то жизнь. Там совсем другие требования, другой инструментарий, другой уровень абстракции. Навскидку — автоматически доказуемая корректность (это для уровня АЭС) и model-driven development (это для уровня самолетов, оно попроще).

O>P.S. Отвечать быстро не смогу, так как занят написанием кода

Вот это прально. Фигачте, товарищ, фигачте. Именно это и приведет Вас в царствие небесное.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.