C# 假设int.Parse对每个项都有效,那么在C语言中将List转换为List的最快方法是什么?

C# 假设int.Parse对每个项都有效,那么在C语言中将List转换为List的最快方法是什么?,c#,performance,list,generics,C#,Performance,List,Generics,我所说的最快是指使用C将列表中的每一项转换为int类型的最有效方法是什么?假设int.Parse对每一项都有效?您无法绕过对所有元素的迭代。使用LINQ: var ints = strings.Select(s => int.Parse(s)); 这增加了额外的好处,它只会在您迭代时转换,并且只转换您请求的元素 如果确实需要列表,请使用ToList方法。但是,您必须知道,上述绩效奖金届时将不可用 var myListOfInts = myListString.Select(x =>

我所说的最快是指使用C将列表中的每一项转换为int类型的最有效方法是什么?假设int.Parse对每一项都有效?

您无法绕过对所有元素的迭代。使用LINQ:

var ints = strings.Select(s => int.Parse(s));
这增加了额外的好处,它只会在您迭代时转换,并且只转换您请求的元素

如果确实需要列表,请使用ToList方法。但是,您必须知道,上述绩效奖金届时将不可用

 var myListOfInts = myListString.Select(x => int.Parse(x)).ToList()
旁注:如果在ICollection.NET框架上调用ToList,则会自动预分配 所需大小的列表,因此不必为添加到列表中的每个新项分配新空间

不幸的是,LinqSelect并没有像Joe在评论中指出的那样返回ICollection

来自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只调用列表构造函数并传入IEnumerable。
列表构造函数非常聪明,如果它是一个ICollection,它会使用最有效的方法来填充列表的新实例。任何明显的方法之间可能都没有什么区别:因此,请选择其他答案中发布的LINQ风格方法之一的可读性

通过将输出列表初始化为其所需的容量,您可能会在非常大的列表中获得一些性能,但您不太可能注意到差异,可读性将受到影响:

List<string> input = ..
List<int> output = new List<int>(input.Count);
... Parse in a loop ...

轻微的性能提升将来自这样一个事实,即输出列表不需要随着其增长而重复重新分配。

如果您真的想要获得最后一点性能,您可以尝试使用指针进行一些操作,例如,但就我个人而言,我会使用其他人提到的简单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

我不知道性能影响是什么,但是有一个List.ConvertAll方法可以将当前列表中的元素转换为另一种类型,返回一个包含已转换元素的列表


这将返回一个IEnumerable,而不是List。我不知道如何在保留所请求的功能的情况下,在不严重牺牲可读性的情况下,更快地执行此操作。@Peter如果它是一个ICollection…-是,但在这种特定情况下不相关,因为Select的输出不是ICollection。我怀疑这是BCL在调用列表上的ToList时自动完成的。如果这是真的,您将一无所获,代码的可读性也会降低。例如:myListOfStrings.Count不迭代获取计数,但它使用myListOfStrings.Count属性。@Petar,是的,当您在任何ICollection上的列表上调用ToList时,就会完成此微优化。但是其他答案中的Linq方法返回一个IEnumerable,在这种情况下将不会执行。尽管如此,我同意你关于可读性的评论,我希望从答案中可以明显看出这一点。在我的答案中添加了解释。当做