最快我的意思是什么是高性能将List中的每个项目转换为使用C#类型int的方法,假设int.Parse适用于每个项目?
答案 0 :(得分:5)
你不会绕过所有元素。使用LINQ:
var ints = strings.Select(s => int.Parse(s));
这有额外的好处,它只会在您迭代它时转换,并且只有你请求的元素。
如果您确实需要列表,请使用ToList
方法。但是,您必须知道上面提到的绩效奖金将无法使用。
答案 1 :(得分:4)
如果你真的想要最后一点表现,你可以尝试使用像this这样的指针,但我个人会选择其他人提到的简单的linq实现。
unsafe static int ParseUnsafe(string value)
{
int result = 0;
fixed (char* v = value)
{
char* str = v;
while (*str != '\0')
{
result = 10 * result + (*str - 48);
str++;
}
}
return result;
}
var parsed = input.Select(i=>ParseUnsafe(i));//optionally .ToList() if you really need list
答案 2 :(得分:2)
任何明显的方法之间可能没有什么区别:因此请考虑可读性(其他答案中发布的LINQ风格方法之一)。
通过将输出列表初始化为所需容量,您可以获得非常大的列表的某些性能,但是您不太可能注意到这种差异,并且可读性会受到影响:
List<string> input = ..
List<int> output = new List<int>(input.Count);
... Parse in a loop ...
轻微的性能提升将来自于输出列表在增长时不需要重复重新分配的事实。
答案 3 :(得分:1)
var myListOfInts = myListString.Select(x => int.Parse(x)).ToList()
附注:如果在ICollection .NET框架上调用ToList(),则会自动预分配 所需大小的列表,因此不必为添加到列表中的每个新项目分配新空间。
不幸的是,LINQ Select不会返回ICollection(正如Joe在评论中指出的那样)。
来自ILSpy:
// System.Linq.Enumerable
public static List<TSource> ToList<TSource>(this IEnumerable<TSource> source)
{
if (source == null)
{
throw Error.ArgumentNull("source");
}
return new List<TSource>(source);
}
// System.Collections.Generic.List<T>
public List(IEnumerable<T> collection)
{
if (collection == null)
{
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.collection);
}
ICollection<T> collection2 = collection as ICollection<T>;
if (collection2 != null)
{
int count = collection2.Count;
this._items = new T[count];
collection2.CopyTo(this._items, 0);
this._size = count;
return;
}
this._size = 0;
this._items = new T[4];
using (IEnumerator<T> enumerator = collection.GetEnumerator())
{
while (enumerator.MoveNext())
{
this.Add(enumerator.Current);
}
}
}
因此,ToList()只调用List构造函数并传入IEnumerable。 List构造函数足够智能,如果它是ICollection,它使用最有效的方式填充List的新实例
答案 4 :(得分:1)
我不知道性能影响是什么,但是有一个List<T>.ConvertAll<TOutput>
方法可以将当前List中的元素转换为另一种类型,返回包含转换元素的列表。