Если кто-то еще ищет ответ, он может использовать функцию уведомления об изменении базы данных Oracle , поставляемую с Oracle 10g. Требуется CHANGE NOTIFICATION
системная привилегия. Вы можете зарегистрировать слушателей, когда вызывать уведомление обратно в приложение.
Несколько комментариев к уже полученным ответам:
ToCharArray
, за которым следует Array.Reverse
будет самым быстрым, но он создает одну «мусорную» копию. StringBuilder
создает одну строку (не массив символов) и манипулирует ею, пока вы не вызовете ToString
]. Никакого дополнительного копирования не требуется ... но есть еще много работы по поддержанию длины и т. д. Какое решение более эффективное? Что ж, мне пришлось бы протестировать его, чтобы иметь хоть какое-то представление, но даже в этом случае это не расскажет всей истории. Вы используете это в ситуации с высоким давлением памяти, когда лишний мусор - настоящая боль? Насколько быстро ваша память по сравнению с вашим процессором и т. Д.?
Как всегда, читаемость обычно король - и в этом вопросе нет ничего лучше, чем ответ Марка. В частности, нет места для единичной ошибки, тогда как мне действительно пришлось бы подумать, чтобы проверить другие ответы. Я не люблю думать. У меня болит мозг, поэтому я стараюсь не делать это очень часто. Использование встроенного Array.Reverse
кажется мне намного лучше. (Хорошо, значит, он все еще не работает с суррогатами и т. Д.,
Самое главное? Это отстой с точки зрения производительности - он должен создать много строк (по одной на символ). Самый простой способ выглядит примерно так:
public static string Reverse(string sz) // ideal for an extension method
{
if (string.IsNullOrEmpty(sz) || sz.Length == 1) return sz;
char[] chars = sz.ToCharArray();
Array.Reverse(chars);
return new string(chars);
}
Проблема в том, что конкатенация строк требует больших затрат, поскольку строки неизменяемы в C #. В приведенном примере на каждой итерации будет создаваться новая строка на один символ длиннее, что очень неэффективно. Чтобы избежать этого, вы должны использовать класс StringBuilder , например:
public string ReverseString(string sz)
{
var builder = new StringBuilder(sz.Length);
for(int i = sz.Length-1; i>=0; i--)
{
builder.Append(sz[i]);
}
return builder.ToString();
}
StringBuilder написан специально для подобных сценариев, поскольку он дает вам возможность объединять строки без недостатка чрезмерного выделения памяти.
Вы заметите, что я предоставил StringBuilder начальную емкость, которую вы редко видеть. Как вы знаете длину результата для начала, это удаляет ненужное выделение памяти.
Обычно происходит то, что он выделяет объем памяти для StringBuilder (по умолчанию 16 символов). Как только содержимое пытается превысить эту емкость, оно удваивает (я думаю) свою емкость и продолжает работать. Это намного лучше, чем выделять память каждый раз, как это происходит с обычными строками, но если вы можете этого избежать, это даже лучше.
Вы заметите, что я предоставил StringBuilder начальную емкость, которую вы не часто видите. Как вы знаете длину результата для начала, это удаляет ненужное выделение памяти.
Обычно происходит то, что он выделяет объем памяти для StringBuilder (по умолчанию 16 символов). Как только содержимое пытается превысить эту емкость, оно удваивает (я думаю) свою емкость и продолжает работать. Это намного лучше, чем выделять память каждый раз, как это происходит с обычными строками, но если вы можете этого избежать, это даже лучше.
Вы заметите, что я предоставил StringBuilder начальную емкость, которую вы не часто видите. Как вы знаете длину результата для начала, это удаляет ненужное выделение памяти.
Обычно происходит то, что он выделяет объем памяти для StringBuilder (по умолчанию 16 символов). Как только содержимое пытается превысить эту емкость, оно удваивает (я думаю) свою емкость и продолжает работать. Это намного лучше, чем выделять память каждый раз, как это происходит с обычными строками, но если вы можете этого избежать, это даже лучше.
Как только содержимое пытается превысить эту емкость, оно удваивает (я думаю) свою емкость и продолжает работать. Это намного лучше, чем выделять память каждый раз, как это происходит с обычными строками, но если вы можете этого избежать, это даже лучше. Как только содержимое пытается превысить эту емкость, оно удваивает (я думаю) свою емкость и продолжает работать. Это намного лучше, чем выделять память каждый раз, как это происходит с обычными строками, но если вы можете этого избежать, это даже лучше.Вместо этого вы можете сделать это в .NET 3.5:
public static string Reverse(this string s)
{
return new String((s.ToCharArray().Reverse()).ToArray());
}
Поскольку строки неизменяемы, каждый оператор + =
создает новую строку, копируя строку на последнем шаге вместе с одним символом для формирования новой строки. По сути, это будет алгоритм O (n 2 ) вместо O (n).
Более быстрый способ будет (O (n)):
// pseudocode:
static string ReverseString(string input) {
char[] buf = new char[input.Length];
for(int i = 0; i < buf.Length; ++i)
buf[i] = input[input.Length - i - 1];
return new string(buf);
}
Лучшим способом решения этой проблемы было бы использование StringBuilder, поскольку он не является неизменяемым, вы не получите ужасного поведения генерации объектов, которое вы получили бы выше. В .net все строки неизменяемы, а это означает, что оператор + = будет создавать новый объект при каждом ударе. StringBuilder использует внутренний буфер, поэтому обращение может быть выполнено в буфере без выделения дополнительных объектов.
Вы должны использовать класс StringBuilder для создания вашей результирующей строки. Строка неизменяема, поэтому, когда вы добавляете строку при каждом взаимодействии цикла, необходимо создавать новую строку, что не очень эффективно.