通过数组(或列表,linkedList,Dictionary ect)的迭代速度是否取决于数据类型?
实施例: 一个10个bool v / s的数组,一个10个整数的数组?
答案 0 :(得分:2)
是的,数据类型很重要。它与迭代无关;它与数据类型有关。
值类型
int
的长度为4个字节。 decimal
的长度为16个字节。因此,decimal
比int
大4倍。每次从数组中检索值时,都会复制该值。如果decimal
,则复制16个字节。 (如果是引用类型,则复制引用,通常为4或8个字节)。复制更多字节只会减慢迭代速度。
<强>拳击强>
如果您通过集合进行迭代,则可能还有更改类型。例如:
foreach(object o in new int[] { 1,2,3 })
....
这会将每int
个框添加到object
。这需要时间。这与迭代无关,它与你拳击的事实有关。
<强>铸造强>
最后一个例子:您还必须投射数组:
foreach(Person p in new object[] { ... })
....
施法也需要额外的时间。
编辑
用于备份我的声明的一些时间测量:
答案 1 :(得分:1)
如果需要,请运行以下代码,但这里是一个快速比较。 它所做的就是迭代数组/列表,并将temp变量设置为该索引中的值。
请注意,现在跑步时Int表现不知所措......不知道为什么......但它也会在重复运行中发生......
namespace Iterating_types
{
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
class Program
{
static void Main(string[] args)
{
Thread.CurrentThread.Priority = ThreadPriority.Highest;
Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.RealTime;
Stopwatch watch = new Stopwatch();
int UPPER = 1000000;
int[] int_arr = Enumerable.Range(1, UPPER).ToArray();
List<int> int_list = Enumerable.Range(1, UPPER).ToList();
Int32[] int32_arr = Enumerable.Range(1, UPPER).ToArray();
Int64[] int64_arr = new Int64[UPPER];
IntObject[] intobject_arr = new IntObject[UPPER];
List<IntObject> intobject_list = new List<IntObject>();
string[] string_arr = new string[UPPER];
List<string> string_list = new List<string>();
bool[] bool_arr = new bool[UPPER];
Boolean[] boolean_arr = new Boolean[UPPER];
List<bool> bool_list = new List<bool>();
List<Boolean> boolean_list = new List<Boolean>();
// Initializing some of the above
for (int i = 0; i < UPPER; i++)
{
int64_arr[i] = (Int64) i;
string_arr[i] = i.ToString();
string_list.Add(i.ToString());
intobject_arr[i] = new IntObject(i);
intobject_list.Add(new IntObject(i));
bool_arr[i] = (i%2 ==0);
boolean_arr[i] = (i%2 ==0);
bool_arr[i] = (i%2 ==0);
bool_list.Add(i%2 ==0);
boolean_list.Add(i%2 == 0);
}
Console.WriteLine("Iterations: {0}{1}", UPPER, Environment.NewLine);
Console.WriteLine("Thread priority: {0}", Thread.CurrentThread.Priority);
Console.WriteLine("Process priority: {0}", Process.GetCurrentProcess().PriorityClass);
Console.WriteLine("\n\rArrays:\t----------------------------------------------");
bool b;
b = bool_arr[1];
watch.Start();
for (int i = 0; i < UPPER; i++)
{
b = bool_arr[i];
}
watch.Stop();
Console.WriteLine("Type: bool\tStructure: Array\tticks: {0}\tMiliSeconds:{1}", watch.ElapsedTicks, watch.ElapsedMilliseconds);
watch.Start();
for (int i = 0; i < UPPER; i++)
{
b = boolean_arr[i];
}
watch.Stop();
Console.WriteLine("Type: Boolean\tStructure: Array\tticks: {0}\tMiliSeconds:{1}", watch.ElapsedTicks, watch.ElapsedMilliseconds);
int temp_int;
temp_int = int_arr[1];
watch.Start();
for (int i = 0; i < UPPER; i++)
{
temp_int = int_arr[i];
}
watch.Stop();
Console.WriteLine("Type: Int\tStructure: Array\tticks: {0}\tMiliSeconds:{1}", watch.ElapsedTicks, watch.ElapsedMilliseconds);
Int32 temp_int32 ;
temp_int32 = int32_arr[1];
watch.Reset();
watch.Start();
for (int i = 0; i < UPPER; i++)
{
temp_int32 = int32_arr[i];
}
watch.Stop();
Console.WriteLine("Type: Int32\tStructure: Array\tticks: {0}\tMiliSeconds:{1}", watch.ElapsedTicks, watch.ElapsedMilliseconds);
Int64 temp_int64 ;
temp_int64 = int64_arr[1];
watch.Reset();
watch.Start();
for (int i = 0; i < UPPER; i++)
{
temp_int64 = int64_arr[i];
}
watch.Stop();
Console.WriteLine("Type: Int64\tStructure: Array\tticks: {0}\tMiliSeconds:{1}", watch.ElapsedTicks, watch.ElapsedMilliseconds);
string s ;
s = string_arr[1];
watch.Reset();
watch.Start();
for (int i = 0; i < UPPER; i++)
{
s = string_arr[i];
}
watch.Stop();
Console.WriteLine("Type: string\tStructure: Array\tticks: {0}\tMiliSeconds:{1}", watch.ElapsedTicks, watch.ElapsedMilliseconds);
temp_int = intobject_arr[1].IntValue;
watch.Reset();
watch.Start();
for (int i = 0; i < UPPER; i++)
{
temp_int = intobject_arr[i].IntValue;
}
watch.Stop();
Console.WriteLine("Type: IntObject\tStructure: Array\tticks: {0}\tMiliSeconds:{1}", watch.ElapsedTicks, watch.ElapsedMilliseconds);
Console.WriteLine("\n\rLists:\t----------------------------------------------");
watch.Reset();
watch.Start();
foreach (var val in bool_list)
{
b = val;
}
watch.Stop();
Console.WriteLine("Type: bool\tStructure: List\t\tticks: {0}\tMiliSeconds:{1}", watch.ElapsedTicks, watch.ElapsedMilliseconds);
watch.Reset();
watch.Start();
foreach (var val in boolean_list)
{
b = val;
}
watch.Stop();
Console.WriteLine("Type: Boolean\tStructure: List\t\tticks: {0}\tMiliSeconds:{1}", watch.ElapsedTicks, watch.ElapsedMilliseconds);
temp_int = int_list.First();
watch.Reset();
watch.Start();
foreach (var val in int_list)
{
temp_int = val;
}
watch.Stop();
Console.WriteLine("Type: Int\tStructure: List\t\tticks: {0}\tMiliSeconds:{1}", watch.ElapsedTicks, watch.ElapsedMilliseconds);
s = string_list.First();
watch.Reset();
watch.Start();
foreach (var val in string_list)
{
s = val;
}
watch.Stop();
Console.WriteLine("Type: string\tStructure: List\t\tticks: {0}\tMiliSeconds:{1}", watch.ElapsedTicks, watch.ElapsedMilliseconds);
temp_int = intobject_list.First().IntValue;
watch.Reset();
watch.Start();
foreach (var val in intobject_list)
{
temp_int = val.IntValue;
}
watch.Stop();
Console.WriteLine("Type: IntObject\tStructure: List\t\tticks: {0}\tMiliSeconds:{1}", watch.ElapsedTicks, watch.ElapsedMilliseconds);
Console.WriteLine();
Console.WriteLine("Hit any key to exit.");
Console.ReadKey();
}
}
class IntObject
{
public int IntValue { get; set; }
public IntObject ()
{
IntValue = 0;
}
public IntObject(int i)
{
IntValue = i;
}
}
}
答案 2 :(得分:-1)
对于参考类型,简单的答案是是,对于值类型,是。
这是因为.NET泛型的实现是以boxing/unboxing is avoided when using Value Types的方式完成的,尽管不在ArrayLists中。例如,List<int>
将数组整数直接存储为堆上的整数而不是对象。在参考类型的情况下,例如List<string>
,List<person>
但是,从对象到数据类型的转换/转换会有一点时间损失。
请参阅comparison between HashSet
and List
using strings and objects。
当您进行大量迭代时,决定在List
,LinkedList
,Dictionary
,HashSet
等之间使用哪一个 >主要是了解它们的存储方式及其运行时间的复杂性。下面列出了一些.NET泛型的实现和渐近索引/迭代时间复杂度:
+------------------+---------------------------------------+-------------------------+-------------+ | | | Item[i] | | | Name | Internal Implementation |------------+------------| Iteration | | | | Avg. Case | Worst Case | | +------------------+---------------------------------------+------------+------------+-------------+ | List | Array | O(1) | O(1) | O(n) | | LinkedList | Doubly Linked List | O(n) | O(n) | O(n) | | Dictionary | Hashtable with links to another array | O(1) | O(n) | O(n) | | HashSet | Hashtable with links to another array | O(1) | O(n) | O(n) | | SortedDictionary | Red-black tree | O(log n) | O(log n) | O(n) | | SortedList | Array | O(1) | O(n) | O(n) | | SortedSet | Red-black tree | O(n) | O(n) | O(n) | +------------------+---------------------------------------+------------+------------+-------------+
总结,可以根据时间复杂度确定迭代这些数据类型的最可能速度。就快速查找项目而言,List
,SortedList
,Dictionary
和HashSet
将始终胜过其他项目,List
和{{SortedList
如果您要处理大量项目然后将 Dictionary
和HashSet
置于大型列表的优势(其中性能),则不建议使用1}}最重要的。)
<强>参考文献:强>