Войти
Подсказки

Ускорение сравнения строк

Автор:

Сам столкнулся с этой проблемой недавно. Может это и не ново, но возможно не все это знают, а если и знают, то не учитывают.

Суть проблемы: если в вашей программе (в частном случае в игре) производится многократное сравнение строк примерно 20-30 тысяч раз в секунду, это не есть хорошо. Большинство конечно понимает, что все это легко и просто заменяется идентификатором целого типа. НО. В данном случае затрудняется читабельность кода при дебагинге. Тобишь надо все время рыться в списках соответсвий дабы понять, что это за объект с таким вот id. Некоторые думают так - "Я не потеряю в скорости ничего, если буду сравнивать строки вместо идентификаторов, так как у меня мало сравнений и вообще потом все переделаю". Обычно, потом количество объектов экспоненциально возрастает, а переделывать становится лень.

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

Вот, собственно, сам клас.

qstring.h

#pragma once

#define QSTRING_MAXCHAR  16

class qstring
{
  char container[QSTRING_MAXCHAR];
  __int64  value;

protected:
  void HashValue( void );

public:
  qstring( void );
  qstring( const char* );
  ~qstring(void);

  void SetValue( const char* );
  const char* GetValue( void ) const;
  const __int64 Value( void ) const { return value; }
  void Clear( void );
  bool Empty( void );

  operator __int64 ( ) const;
  operator const char* ( ) const;
  bool operator == ( qstring v ) const;
  bool operator == ( int v ) const;
  bool operator != ( qstring v ) const;
  qstring& operator = ( const char* v );

  bool operator < ( qstring v ) const
  {
    return v.value < value;
  }

  bool operator > ( qstring v ) const
  {
    return v.value > value;
  }

  bool operator <= ( qstring v ) const
  {
    return v.value <= value;
  }

  bool operator >= ( qstring v ) const
  {
    return v.value >= value;
  }
};

qstring.cpp

#include "qstring.h"
#include <Windows.h>

qstring::qstring(void)
{
  memset(container, 0, QSTRING_MAXCHAR);
  value = 0;
}

qstring::qstring( const char* v )
{
  memset(container, 0, QSTRING_MAXCHAR);
  SetValue( v );
}

void qstring::Clear( void )
{
  memset(container, 0, QSTRING_MAXCHAR);
  value = 0;
}

bool qstring::Empty( void )
{
  return value == 0;
}

qstring::~qstring(void)
{
}

void qstring::SetValue( const char* v )
{
  // Save string value
  int str_len = (int)strlen(v);
  if (str_len > QSTRING_MAXCHAR)
    str_len = QSTRING_MAXCHAR;

  value = 0;

  strncpy( container, v, str_len );

  // Hash string value into __int64
  int c = 0;
  for (int i=0; i < str_len; i++)
  {
    if ( i % 2 )
      value = value + (container[i] << c);
    else
    {
      value = value + ((container[i]*2) << c);
      c++;
    }
  }
}

const char* qstring::GetValue( void ) const
{
  return container;
}

qstring::operator __int64 ( ) const
{
  return value;
}

qstring::operator const char* ( ) const
{
  return container;
}

bool qstring::operator == ( qstring v ) const
{
  return v.value == value;
}

bool qstring::operator == ( int v ) const
{
  return v == value;
}

bool qstring::operator != ( qstring v ) const
{
  return v.value != value;
}

qstring& qstring::operator = ( const char* v )
{
  SetValue( v );
  return *this;
}

Для ускорения работы класса можно перенести частоиспользуемые функции в inline.

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

2 октября 2003