Обход строки на скрость)
От: Greo  
Дата: 08.05.10 11:45
Оценка:
Тривиальная задача:
есть строка типа "asd hghhhhh rte", однако размером эдак символов 10к. Необходимо выделить все слова в этой строке(то есть до пробела).
Есть ли что-нудь быстрее обычного цикла for с последовательным хождением по строке и записью всех символов до очередного пробела в другую строку?
Пробовал копаться в string функциях, пока ничего быстрее не нашел) Хотя это наверное логично, т.к. наверняка они на такого рода циклах и построены.
Есть ли возможность на ассемблере обогнать for?
Re: Обход строки на скрость)
От: Геннадий Майко США  
Дата: 08.05.10 13:34
Оценка: :)
Здравствуйте, Greo,

G>есть строка типа "asd hghhhhh rte", однако размером эдак символов 10к. Необходимо выделить все слова в этой строке(то есть до пробела).

G>Есть ли что-нудь быстрее обычного цикла for с последовательным хождением по строке и записью всех символов до очередного пробела в другую строку?
--
Так как задача разбивается на две (поиск пробелов и копирование слов), которые могут выполняться паралельно, то попробуйте в одном потоке искать пробелы и найденные индексы передавать другим потокам для копирования самих слов.

C уважением,
Геннадий Майко.
Re: Обход строки на скрость)
От: 8001 Россия  
Дата: 09.05.10 10:10
Оценка: 6 (1) +1
Здравствуйте, Greo, Вы писали:

G>Тривиальная задача:

G>есть строка типа "asd hghhhhh rte", однако размером эдак символов 10к. Необходимо выделить все слова в этой строке(то есть до пробела).
G>Есть ли что-нудь быстрее обычного цикла for с последовательным хождением по строке и записью всех символов до очередного пробела в другую строку?
G>Пробовал копаться в string функциях, пока ничего быстрее не нашел) Хотя это наверное логично, т.к. наверняка они на такого рода циклах и построены.
G>Есть ли возможность на ассемблере обогнать for?


Попробуйте ещё раз! Вот как работает strchr() из newlib:


/*
FUNCTION
    <<strchr>>---search for character in string

INDEX
    strchr

ANSI_SYNOPSIS
    #include <string.h>
    char * strchr(const char *<[string]>, int <[c]>);

TRAD_SYNOPSIS
    #include <string.h>
    char * strchr(<[string]>, <[c]>);
    const char *<[string]>;
    int <[c]>;

DESCRIPTION
    This function finds the first occurence of <[c]> (converted to
    a char) in the string pointed to by <[string]> (including the
    terminating null character).

RETURNS
    Returns a pointer to the located character, or a null pointer
    if <[c]> does not occur in <[string]>.

PORTABILITY
<<strchr>> is ANSI C.

<<strchr>> requires no supporting OS subroutines.

QUICKREF
    strchr ansi pure
*/

#include <string.h>
#include <limits.h>

/* Nonzero if X is not aligned on a "long" boundary.  */
#define UNALIGNED(X) ((long)X & (sizeof (long) - 1))

/* How many bytes are loaded each iteration of the word copy loop.  */
#define LBLOCKSIZE (sizeof (long))

#if LONG_MAX == 2147483647L
#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
#else
#if LONG_MAX == 9223372036854775807L
/* Nonzero if X (a long int) contains a NULL byte. */
#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
#else
#error long int is not a 32bit or 64bit type.
#endif
#endif

/* DETECTCHAR returns nonzero if (long)X contains the byte used
   to fill (long)MASK. */
#define DETECTCHAR(X,MASK) (DETECTNULL(X ^ MASK))

char *
_DEFUN (strchr, (s1, i),
    _CONST char *s1 _AND
    int i)
{
  _CONST unsigned char *s = (_CONST unsigned char *)s1;
  unsigned char c = i;

#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
  unsigned long mask,j;
  unsigned long *aligned_addr;

  /* Special case for finding 0.  */
  if (!c)
    {
      while (UNALIGNED (s))
        {
          if (!*s)
            return (char *) s;
          s++;
        }
      /* Operate a word at a time.  */
      aligned_addr = (unsigned long *) s;
      while (!DETECTNULL (*aligned_addr))
        aligned_addr++;
      /* Found the end of string.  */
      s = (const unsigned char *) aligned_addr;
      while (*s)
        s++;
      return (char *) s;
    }

  /* All other bytes.  Align the pointer, then search a long at a time.  */
  while (UNALIGNED (s))
    {
      if (!*s)
        return NULL;
      if (*s == c)
        return (char *) s;
      s++;
    }

  mask = c;
  for (j = 8; j < LBLOCKSIZE * 8; j <<= 1)
    mask = (mask << j) | mask;

  aligned_addr = (unsigned long *) s;
  while (!DETECTNULL (*aligned_addr) && !DETECTCHAR (*aligned_addr, mask))
    aligned_addr++;

  /* The block of bytes currently pointed to by aligned_addr
     contains either a null or the target char, or both.  We
     catch it using the bytewise search.  */

  s = (unsigned char *) aligned_addr;

#endif /* not PREFER_SIZE_OVER_SPEED */

  while (*s && *s != c)
    s++;
  if (*s == c)
    return (char *)s;
  return NULL;
}
Re: Обход строки на скрость)
От: Rostislav_Pro  
Дата: 09.05.10 13:27
Оценка:
Здравствуйте, Greo, Вы писали:

G>Тривиальная задача:

G>есть строка типа "asd hghhhhh rte", однако размером эдак символов 10к. Необходимо выделить все слова в этой строке(то есть до пробела).
G>Есть ли что-нудь быстрее обычного цикла for с последовательным хождением по строке и записью всех символов до очередного пробела в другую строку?
G>Пробовал копаться в string функциях, пока ничего быстрее не нашел) Хотя это наверное логично, т.к. наверняка они на такого рода циклах и построены.
G>Есть ли возможность на ассемблере обогнать for?

А чем плохо просто заменить все пробелы на '\0'? Ну и указатели на начала слов куда-нибудь сохранять.
Re: Обход строки на скрость)
От: gear nuke  
Дата: 10.05.10 05:41
Оценка:
Здравствуйте, Greo, Вы писали:

G>есть строка типа "asd hghhhhh rte", однако размером эдак символов 10к. Необходимо выделить все слова в этой строке(то есть до пробела).


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

Возможно, стоит подумать, как лучше предаставить в памяти полученные слова. Нпример, если по ним потом будет идти поиск, то использование префиксных деревьев даст заметно более ощутимый выигрыш по скорости (и даже памяти).
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.