Эффективный способ реализовать IsAscii () в C # - PullRequest
1 голос
/ 06 марта 2012

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

private bool IsAscii(char c)
{
  return ((int)c < 128);
}

Эта функция используется в программе обработки журналов и поэтому вызывается для каждого символа в журнале внутри замкнутого цикла.(но некоторые другие функции, такие как Char.IsLetterOrDigit (), кажется, не такие дорогие.)

Я также попробовал несколько вариантов, причем все они немного медленнее, чем показанная выше, или имеют аналогичную производительность.,Интересно, я делаю что-то в корне неправильно, поскольку я новичок в C #.

Вариации: -

// similar
private bool IsAscii(char c)
{
  return (c < 128);
}

-

// slower
private bool IsAscii(char c)
{
  return (Convert.ToInt32(c) < 128);
}

-

// similar
private bool IsAscii(char c)
{
  return ((c & (~0x7f)) == 0);
}

-

// slower
// class member
private char asciiend = Char.ConvertFromUtf32(128)[0];
private bool IsAscii(char c)
{
  return (c.CompareTo(asciiend) < 0);
}

-

Ответы [ 4 ]

2 голосов
/ 06 марта 2012

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

1 голос
/ 06 марта 2012

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

Обратите внимание, что в .NET Framework 4.5 вводится MethodImplOptions.AggressiveInlining.

0 голосов
/ 06 марта 2012

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

Попробуйте построить сборку релиза и добавить несколько профилей домашнего изготовления (используйте Stopwatch), чтобы измерить время, необходимое для просмотра большого файла журнала.Запустите его, не подключая его к Visual Studio (либо снаружи, либо запустив его с помощью CTRL-F5).Если моя догадка верна, вы увидите, что производительность резко улучшится, потому что джиттер будет свободен для линейного выделения.

Вы также можете указать джиттеру выполнить его оптимизацию во время работы под отладчиком.Переключиться на выпуск сборки, перейдите в Инструменты |Варианты |Отладка |Общие и снимите флажок «Подавить оптимизацию JIT при загрузке модуля».

И как только вы решите проблему с производительностью, вы действительно хотите, чтобы IsAscii был методом расширения для типа Char - это имеет больше смысла в этом смысле (но выиграл 'решить вашу проблему с производительностью)

0 голосов
/ 06 марта 2012

Как насчет использования Encoding объекта из System.Text?

String ascii = Encoding.ASCII.GetString(Encoding.ASCII.GetBytes(originalString));

Хотя я не на 100% уверен, что знаю, что такое намерение, или это жизнеспособноопция.

...