- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
xash_force_inline size_t Q_strncat( char *dst, const char *src, size_t size )
{
register const char *pchr;
register const unsigned int *plongword;
register unsigned int *pdst;
register unsigned int len;
const unsigned int himagic = 0x80808080, lomagic = 0x01010101;
if( !dst || !src || !size )
return 0;
len = Q_strlen( dst );
dst += len;
if( ( unsigned long int )src & ( sizeof( int ) - 1) != ( unsigned long int )dst & ( sizeof( int ) - 1) )
return len + Q_strncpy_unaligned( dst, src, size - len );
// first, copy all unaligned bytes
for( pchr = src; ( ( unsigned long int )pchr & ( sizeof( int ) - 1) ) != 0; pchr++, len++, dst++ )
{
*dst = *pchr;
if( len >= size )
{
*dst = '\0';
return len;
}
if( *pchr == '\0' )
return len;
}
plongword = ( const unsigned int * ) pchr;
pdst = ( unsigned int * ) dst;
// plongword is aligned now, copy by 4 bytes
while( true )
{
register unsigned int longword = *plongword++;
// if magic check failed
if( ( ( longword - lomagic ) & himagic ) != 0 || (size - len < 4) )
{
const char *pchar = ( const char * )( plongword - 1 );
char *pchdst = ( char * )( pdst );
int i;
for( i = 0; i < 4; i++ )
{
pchdst[i] = pchar[i];
if( len + i >= size )
{
pchdst[i] = '\0';
return len + i;
}
if( pchar[i] == 0 )
return len + i;
}
}
len += sizeof( longword );
*pdst++ = longword;
}
return 0;
}
/*
* sanity checker
xash_force_inline size_t Q_strncat( char *dst, const char *src, size_t size )
{
char buf1[100000], buf2[100000], r1, r2;
if( !dst || !src || !size )
return 0;
if( size > 99999 )
size = 99999;
strncpy( buf1, dst, size );
strncpy( buf2, dst, size );
buf1[99999] = buf2[99999] = 0;
r1 = Q_strncat_( buf1, src, size );
r2 = Q_strncat2( buf2, src, size );
if( r1 != r2 )
printf("DIFFERENT RESULT %d %d %d %d %s\n%s\n", r1, r2, aligned, counter, buf1, src);
if( strcmp( buf1, buf2 ) )
{
printf("DIFFERENT DATA %s %d %d %d %4s\n", src, size, aligned, counter, last);
printf("1: %s\n", buf1);
printf("2: %s\n", buf2);
}
//strncpy( dst, buf1, size );
return Q_strncat2(dst, src, size);
}
*/
Оптимизация удалась, однако при виде этого кода становится не по себе. Что можно с этим сделать?
Steve_Brown 27.05.2016 10:27 # +2
(0x10203040 - 0x01010101) & 0x80808080 == 0 // magic
(0x10001C1C - 0x01010101) & 0x80808080 == 0x0EFF1B1B // no magic, '\0'
(0xE0EFEEE6 - 0x01010101) & 0x80808080 == 0xDFEEEDE5 // no magic?
Оптимизируются только строки в ASCII?
mittorn 27.05.2016 13:08 # 0
Такая провкрка заюзана в strlen в android и в glibc.
Я предположил, что она действительно работает
Steve_Brown 27.05.2016 14:16 # 0
Ну разве что так.
guest 27.05.2016 14:27 # 0
Steve_Brown 27.05.2016 14:18 # +3
Antervis 27.05.2016 11:31 # 0
mittorn 27.05.2016 13:04 # +1
j123123 27.05.2016 11:42 # +2
То ли дело пацкалестроки
guesto 27.05.2016 12:55 # 0
kerman 28.05.2016 01:08 # +2
А по делу, где-то terminatedzero катит, где-то паскалеизвращение, где-то верёвки... Все способы мудацкие, но серебрянной пули нет )
guesto 28.05.2016 01:35 # 0
Например в статье "как микрософт проиграла битву за API" он наделал кучу предсказаний, и ни одно не сбылось. Чего стоит только высер про нет:
В статье "Making Wrong Code Look Wrong" он предлагает использовать венгерскую нотацию зачем-то сокращая слова. Тоесть вместо "rowSize" называть переменную "rwSize" да еще и пишет на vbs. А еще пишет про какого-то Raymond Chen который "the best programmer in the world". Что бля? Что он сделал кроме книжки про "old new thing"?
kerman 28.05.2016 01:46 # +2
В статье "Making Wrong Code Look Wrong" он ни хуя не предлагает использовать венгерскую нотацию. Даже скорее наоборот. Там он раскрыл хорошую тему некорректного применения этой самой нотации и привёл примеры, как это должно работать.
Raymond Chen не читал, но осуждаю.
guesto 28.05.2016 03:17 # −1
kerman 29.05.2016 00:00 # 0
guesto 30.05.2016 03:30 # −1
j123123 28.05.2016 13:38 # +2
Ну да, вон они уже убунту в свою винду встраивают официально, с поддержкой нативных системных вызовов
guesto 28.05.2016 13:40 # 0
inkanus-gray 28.05.2016 02:01 # +3
При беглом прочтении показалось, что маляра звали Шамилем.
kegdan 28.05.2016 15:58 # +3
Dummy00001 28.05.2016 03:16 # +1
повесится.
если у тебя `strcat()` является ботллнеком, то ты что-то капитально неправильно делаешь.
я уже 5+ лет заменяю стандартный ебанутый strncat() на нечто типа:
но чаще я пользуюсь самописной `strncatfmt()` которая формат + ... передает вместо строки.
bormand 28.05.2016 08:07 # 0
bormand 28.05.2016 08:47 # 0
bormand 28.05.2016 09:07 # +2
guesto 28.05.2016 13:56 # +5
Dummy00001 28.05.2016 13:58 # 0
по моему личному опыту, возврат strcat()'а никому не нужен.
strcat() и даже strncat() - это неэффективное убогое говно, и те кто ими пользуются/в тах местах где ими пользуются, "эффективность" просто и рядом не стояла. почему и на возврат всем посрать.
и chained strcat()ы это все равно говно - по сравнению с одним snprintf()'ом.
> З.Ы. Я вообще в одном сишном проекте сорвался и сделал нормальные строки с size и capacity...
аналогично. но в 80% случаев, мудачество с strcat() просто заменяется одним snprintf()'ом.
guesto 28.05.2016 14:01 # +1
Dummy00001 28.05.2016 14:51 # +4
mittorn 29.05.2016 09:26 # 0
mittorn 28.05.2016 10:32 # 0
Dummy00001 28.05.2016 13:52 # 0
j123123 28.05.2016 14:36 # 0
bormand 28.05.2016 16:35 # +1
snprintf?
> многопоточно
У тебя строки такой длины, что это даст плюс и код не погрязнет в синхронизациях?
j123123 28.05.2016 18:20 # 0
bormand 28.05.2016 18:28 # 0
Ну во-первых когда запускаешь треды и когда ждёшь их завершения. Во-вторых - на том же интеле из-за когерентности кеша очень плохо работает запись в общую память (кеши ядер отбирают друг у друга владение кешлайном).
guesto 28.05.2016 18:33 # 0
Другой вопрос что можно сделать фолс шаринг случайно
Для того и есть intel vtune
bormand 28.05.2016 18:37 # 0
О нём и речь. Ну хотя х.з., границы строк довольно редко, потоков мало. Не должно сильно напрягать.
guesto 28.05.2016 18:38 # 0
bormand 28.05.2016 18:32 # 0
meinf 28.05.2016 22:15 # 0
ага, вот только тебе надо сразу знать сколько каждый тред обработает, чтоб разделить эту память так, чтоб в нее можно было писать параллельно без установки ей единственного владельца
то бишь тебе сначала придется посчитать длину строк и как то раскидать их по тредам
bormand 28.05.2016 22:21 # 0
>> Если использовать не просто нуль терминированные строки, но еще и хранить длину самой строки
meinf 28.05.2016 22:30 # 0
правда если они все фиксированной длины - будет попроще, но тогда получается какая то через чур надуманная задача
bormand 28.05.2016 10:46 # +2
uintptr_t же. А то на всяких вендах long слишком короткий...
gost 28.05.2016 13:57 # 0
mittorn 29.05.2016 09:30 # +1