Это оказывается удивительно хитрым вопросом.
я рекомендовал бы использовать Массив. Реверс для большинства случаев, поскольку это кодируется исходно и очень просто поддержать и понять.
Это, кажется, превосходит StringBuilder по характеристикам во всех случаях, которые я протестировал.
public string Reverse(string text)
{
if (text == null) return null;
// this was posted by petebob as well
char[] array = text.ToCharArray();
Array.Reverse(array);
return new String(array);
}
существует второй подход, который может быть быстрее для определенных длин строки который Xor использования.
public static string ReverseXor(string s)
{
if (s == null) return null;
char[] charArray = s.ToCharArray();
int len = s.Length - 1;
for (int i = 0; i < len; i++, len--)
{
charArray[i] ^= charArray[len];
charArray[len] ^= charArray[i];
charArray[i] ^= charArray[len];
}
return new string(charArray);
}
Примечание , Если Вы хотите поддерживать полный набор символов Unicode UTF16 , считало это . И используйте реализацию там вместо этого. Это может быть далее оптимизировано при помощи одного из вышеупомянутых алгоритмов и пробежки строки для чистки его после того, как символы будут инвертированы.
Вот сравнение производительности StringBuilder, Массива. Reverse и метод Xor.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
namespace ConsoleApplication4
{
class Program
{
delegate string StringDelegate(string s);
static void Benchmark(string description, StringDelegate d, int times, string text)
{
Stopwatch sw = new Stopwatch();
sw.Start();
for (int j = 0; j < times; j++)
{
d(text);
}
sw.Stop();
Console.WriteLine("{0} Ticks {1} : called {2} times.", sw.ElapsedTicks, description, times);
}
public static string ReverseXor(string s)
{
char[] charArray = s.ToCharArray();
int len = s.Length - 1;
for (int i = 0; i < len; i++, len--)
{
charArray[i] ^= charArray[len];
charArray[len] ^= charArray[i];
charArray[i] ^= charArray[len];
}
return new string(charArray);
}
public static string ReverseSB(string text)
{
StringBuilder builder = new StringBuilder(text.Length);
for (int i = text.Length - 1; i >= 0; i--)
{
builder.Append(text[i]);
}
return builder.ToString();
}
public static string ReverseArray(string text)
{
char[] array = text.ToCharArray();
Array.Reverse(array);
return (new string(array));
}
public static string StringOfLength(int length)
{
Random random = new Random();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++)
{
sb.Append(Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65))));
}
return sb.ToString();
}
static void Main(string[] args)
{
int[] lengths = new int[] {1,10,15,25,50,75,100,1000,100000};
foreach (int l in lengths)
{
int iterations = 10000;
string text = StringOfLength(l);
Benchmark(String.Format("String Builder (Length: {0})", l), ReverseSB, iterations, text);
Benchmark(String.Format("Array.Reverse (Length: {0})", l), ReverseArray, iterations, text);
Benchmark(String.Format("Xor (Length: {0})", l), ReverseXor, iterations, text);
Console.WriteLine();
}
Console.Read();
}
}
}
Вот результаты:
26251 Ticks String Builder (Length: 1) : called 10000 times.
33373 Ticks Array.Reverse (Length: 1) : called 10000 times.
20162 Ticks Xor (Length: 1) : called 10000 times.
51321 Ticks String Builder (Length: 10) : called 10000 times.
37105 Ticks Array.Reverse (Length: 10) : called 10000 times.
23974 Ticks Xor (Length: 10) : called 10000 times.
66570 Ticks String Builder (Length: 15) : called 10000 times.
26027 Ticks Array.Reverse (Length: 15) : called 10000 times.
24017 Ticks Xor (Length: 15) : called 10000 times.
101609 Ticks String Builder (Length: 25) : called 10000 times.
28472 Ticks Array.Reverse (Length: 25) : called 10000 times.
35355 Ticks Xor (Length: 25) : called 10000 times.
161601 Ticks String Builder (Length: 50) : called 10000 times.
35839 Ticks Array.Reverse (Length: 50) : called 10000 times.
51185 Ticks Xor (Length: 50) : called 10000 times.
230898 Ticks String Builder (Length: 75) : called 10000 times.
40628 Ticks Array.Reverse (Length: 75) : called 10000 times.
78906 Ticks Xor (Length: 75) : called 10000 times.
312017 Ticks String Builder (Length: 100) : called 10000 times.
52225 Ticks Array.Reverse (Length: 100) : called 10000 times.
110195 Ticks Xor (Length: 100) : called 10000 times.
2970691 Ticks String Builder (Length: 1000) : called 10000 times.
292094 Ticks Array.Reverse (Length: 1000) : called 10000 times.
846585 Ticks Xor (Length: 1000) : called 10000 times.
305564115 Ticks String Builder (Length: 100000) : called 10000 times.
74884495 Ticks Array.Reverse (Length: 100000) : called 10000 times.
125409674 Ticks Xor (Length: 100000) : called 10000 times.
кажется, что Xor может быть быстрее для коротких строк.
Есть несколько разных способов сделать это:
Вместо того, чтобы объявлять его как глобальную переменную, оберните его в одноэлементном объекте, затем сделайте одноэлементный объект доступным где угодно (путем # импорта файла .h)
Создайте файл .h, например "Globals.h". В .h объявите свой массив как extern NSMutableArray * myGlobalArray;
Затем в другом месте вашего приложения (AppDelegate - хорошее место) просто выполните: myGlobalArray = [[NSMutableArray alloc] init];
Тогда в любом месте, где вам понадобится массив, просто #import " этот подход (как и №3) отделяет объявление от инициализации (т.е. объект не создается рядом с тем местом, где он объявлен). Кто-то может возразить, что это неправильно, и они могут быть правы.
Вариант №3 хорош, потому что тогда вам никогда не придется забывать #import что-либо вообще. Однако здесь возникают те же вопросы, что и при варианте № 2.
Четвертый ответ - объявить массив в вашем UIApplicationDelegate
и получить к нему доступ через
[[[UIApplication sharedApplication] delegate] myArray];
. В тех случаях, когда мне просто нужно несколько глобальных объектов, я обнаружил, что это самый простой и чистый способ сделать это.
Если вы планируете сохранить какие-то общие настройки для вашего приложения, используйте [NSUserDefaults sharedDefaults] для сохранения простых данных, которые можно использовать в приложении. Если вы храните временные данные, то «статический» подход будет работать, как и везде.
Однако, вероятно, лучше использовать одноэлементный объектный подход с аксессором класса, например NSUserDefaults, а затем предоставить методы доступа к экземпляру для получения ваших данных. Таким образом вы изолируете себя от возможных изменений структуры данных в будущем. Затем вы должны использовать статическую переменную, как указано выше, но в файле .m (и, следовательно, вам не нужно определение extern). Обычно это выглядит так:
static Foo *myDefault = nil;
@implementation Foo
+(Foo)defaultFoo {
if(!myDefault)
myDefault = [[Foo alloc] init]; // effective memory leak
return myDefault;
}
@end
Тогда у вас будут аксессоры экземпляра,
Кажется, что у всех здесь есть неявная, опущенная первая строка: «Вы можете сделать это в стиле C K&R, или ...»
Да, вы все еще можете делать это в стиле C.
В файле 1:
NSArray *MyArray;
В файле 2:
extern NSArray *MyArray;
Здесь играет Captain Obvious.