【发布时间】:2019-07-18 10:26:28
【问题描述】:
基本上我在 codewars 网站上做一个code kata 在开始编码之前有点“热身”,并注意到一个问题,我不知道是因为我的代码,还是只是常规问题。
public static string WhoIsNext(string[] names, long n)
{
Queue<string> fifo = new Queue<string>(names);
for(int i = 0; i < n - 1; i++)
{
var name = fifo.Dequeue();
fifo.Enqueue(name);
fifo.Enqueue(name);
}
return fifo.Peek();
}
并且是这样调用的:
// Test 1
string[] names = { "Sheldon", "Leonard", "Penny", "Rajesh", "Howard" };
long n = 1;
var nth = CodeKata.WhoIsNext(names, n); // n = 1 Should return sheldon.
// test 2
string[] names = { "Sheldon", "Leonard", "Penny", "Rajesh", "Howard" };
long n = 52;
var nth = CodeKata.WhoIsNext(names, n); // n = 52 Should return Penny.
// test 3
string[] names = { "Sheldon", "Leonard", "Penny", "Rajesh", "Howard" };
long n = 7230702951;
var nth = CodeKata.WhoIsNext(names, n); // n = 52 Should return Leonard.
在这段代码中,当我将 long n 的值放入 7230702951(一个非常高的数字......)时,它会引发内存不足异常。数字那么高,还是队列只是没有针对这些数字优化。
我这样说是因为我尝试使用 List 并且列表内存使用量保持在 500 MB 以下(顺便说一句,平台大约是 327MB),并且运行了大约 2/3 分钟,而队列在几秒钟内引发了异常,仅在那段时间就超过了 2GB。
有人可以向我解释为什么会发生这种情况,我只是好奇吗?
编辑 1
我忘了添加列表代码:
public static string WhoIsNext(string[] names, long n)
{
List<string> test = new List<string>(names);
for(int i = 0; i < n - 1; i++)
{
var name = test[0];
test.RemoveAt(0);
test.Add(name);
test.Add(name);
}
return test[0];
}
编辑 2
对于那些说代码加倍名称并且无效的人,我已经知道,代码不是有用的,只是一个 kata。 (我现在更新了链接!)
我的问题是,为什么 Queue 比具有高计数的 List 效率低得多。
【问题讨论】:
-
嗯,这取决于
names中有多少值,可能很多很多,这显然会增加使用的内存。然后你将它们添加到队列中两次,不清楚这段代码实际上应该做什么。 -
在我展示的示例中,字符串 [] 名称始终以 5 个名称开头。我只是好奇为什么队列会在几秒钟内超过 2gb,而列表即使在添加值时也一直保持在 326MB,我的意思是自从我开始写这个问题以来,我正在使用 7230702951 运行循环,以及内存使用情况不再增加。
-
不确定,可以查看Queue<T> code和List<T> code
-
代码其实很简单很短,其实就是那个函数,我会更新来展示我是如何调用这个函数的!