C# 执行此代码最有效的方法是什么?
我的老师要求我们尽可能以最有效的方式制作一个程序,并为此使用一个开关盒 程序要求用户输入,根据用户输入的内容,程序必须遵循一组指令 如果输入为“A”或“A”,则数组必须从A到Z排序 如果输入为“Z”或“Z”,则必须将数组从Z排序到A 如果输入为“R”或“R”,则必须反转数组 数组是字符串[] 所以我想知道使用它是否更有效C# 执行此代码最有效的方法是什么?,c#,arrays,sorting,C#,Arrays,Sorting,我的老师要求我们尽可能以最有效的方式制作一个程序,并为此使用一个开关盒 程序要求用户输入,根据用户输入的内容,程序必须遵循一组指令 如果输入为“A”或“A”,则数组必须从A到Z排序 如果输入为“Z”或“Z”,则必须将数组从Z排序到A 如果输入为“R”或“R”,则必须反转数组 数组是字符串[] 所以我想知道使用它是否更有效 switch (choice.ToLower()) { case "a": Array.Sort(array); break;
switch (choice.ToLower())
{
case "a":
Array.Sort(array);
break;
case "z":
Array.Sort(array);
Array.Reverse(array);
break;
case "r":
Array.Reverse(array);
break;
}
或
此外,如果该代码可以进一步优化
那么,使用开关盒或上述if结构的最有效方法是什么,并解释原因
我只是好奇,因为我总是尽量优化我所有的代码。在你的例子中,if的速度较慢,因为每次它都检查两个条件。还应检查有关
开关
vsif
速度的信息。(在您使用if的示例中,始终检查的4个条件)。
如果一个开关
包含五个以上的元素,它将使用一个查找表或一个哈希表来实现,这意味着所有项目都获得相同的访问时间,而如果开关的列表中最后一个项目需要花费更多的时间来访问,因为它必须首先评估之前的每个条件。,您可以自己检查:
class Program
{
static void MyMethod1(int[] array, string choice)
{
switch (choice.ToLower())
{
case "a":
Array.Sort(array);
break;
case "z":
Array.Sort(array);
Array.Reverse(array);
break;
case "r":
Array.Reverse(array);
break;
}
}
static void MyMethod2(int[] array, string choice)
{
if (choice.ToLower() == "a" || choice.ToLower() == "z")
{
Array.Sort(array);
}
if (choice.ToLower() == "r" || choice.ToLower() == "z")
{
Array.Reverse(array);
}
}
static int[][] CreateRandomArrays(int num, int length)
{
Random rand = new Random();
int[][] arrays = new int[num][];
for (int i = 0; i < arrays.Length; i++)
{
arrays[i] = new int[length];
for (int i2 = 0; i2 < length; i2++)
arrays[i][i2] = rand.Next();
}
return arrays;
}
static void Main(string[] args)
{
int[][] test1 = CreateRandomArrays(50, 200000);
int[][] test2 = CreateRandomArrays(50, 200000);
Stopwatch s = new Stopwatch();
s.Start();
for (int i = 0; i < test1.Length; i++) MyMethod1(test1[i], "z");
s.Stop();
Console.WriteLine(s.ElapsedMilliseconds);
s.Restart();
for (int i = 0; i < test2.Length; i++) MyMethod2(test2[i], "z");
s.Stop();
Console.WriteLine(s.ElapsedMilliseconds);
}
}
ToUpper更快+使用Linq,在连接部件之前不会执行订购操作
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static string[] words = {
"what", "is", "the", "most", "effecient", "way", "to", "execute", "this", "code"
};
static void Main(string[] args)
{
IEnumerable<string> result;
Console.Write("Choose words order (A to Z (A), Z to A (Z), Reversed (R)): ");
switch (Console.ReadLine().ToUpper())
{
case "A": result = words.OrderBy(w => w); break;
case "Z": result = words.OrderByDescending(w => w); break;
case "R": result = words.Reverse(); break;
default: result = words.AsEnumerable(); break;
}
Console.WriteLine(string.Join(" ", result));
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
班级计划
{
静态字符串[]字={
“what”、“is”、“the”、“most”、“effecient”、“way”、“to”、“execute”、“this”、“code”
};
静态void Main(字符串[]参数)
{
可数结果;
控制台。写(“选择单词顺序(A到Z(A),Z到A(Z),反转(R)):”;
开关(Console.ReadLine().ToUpper())
{
案例“A”:结果=words.OrderBy(w=>w);中断;
大小写“Z”:结果=单词.OrderByDescending(w=>w);break;
案例“R”:结果=单词。反转();中断;
默认值:result=words.AsEnumerable();break;
}
Console.WriteLine(string.Join(“,result));
}
}
第一个更有效,因为它只调用一次ToLower。但它们都编译成if-else。在带开关的编译代码中,ToLower()
保存在局部变量中,如果有,则检查其值。然而,在第二个版本中,ToLower方法可能会被调用1次到4次。至少直接按相反顺序排序要比按相反顺序排序快,如果您也关心这一点,您是否尝试过对其进行基准测试?在功能上,这两种方法是等效的;然而,如果练习的重点是使用switch语句,那么这应该是您的重点。你可能想读书。这是一篇较老的帖子,但这种观点仍然适用。在学习时,性能应该是最不重要的因素。因此,如果我在执行代码之前将choice.ToLower存储在choice中,然后在if结构中省略ToLower,那么执行速度会更快吗?这还不清楚。字符串开关使用的哈希表可能会慢一些。@usr我的回答中包含了这个案例。事实上,这是真的,因为他的案例只有不到五个条件。我没有注意到。这是非常有用的代码,谢谢,我在更改选项时得到的结果。在if结构中,ToLower使其只被调用一次,结果是:1749 ms vs 1694ms@JesseVerbruggen尽一切办法。请随意使用这个简单的基准测试来测试性能。。。正如其他人所说,ToUpper()比ToLower()更好。我建议这两种方法99%的执行时间都是Sort()
和Reverse()
方法所必需的,而不是if
或switch
语句为开关添加一个默认值要比不使用它好吗?因为当输入不是a、z或r时,无需执行任何操作。建议:
1010 ms vs 1008 ms
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static string[] words = {
"what", "is", "the", "most", "effecient", "way", "to", "execute", "this", "code"
};
static void Main(string[] args)
{
IEnumerable<string> result;
Console.Write("Choose words order (A to Z (A), Z to A (Z), Reversed (R)): ");
switch (Console.ReadLine().ToUpper())
{
case "A": result = words.OrderBy(w => w); break;
case "Z": result = words.OrderByDescending(w => w); break;
case "R": result = words.Reverse(); break;
default: result = words.AsEnumerable(); break;
}
Console.WriteLine(string.Join(" ", result));
}
}