这段代码的最有效执行方式是什么?

5

我的老师让我们尽可能高效地编写一个程序,并使用 switch case。该程序会要求用户输入,根据输入的内容,程序将执行一系列指令。

如果输入为"A"或"a",则必须将数组从A到Z进行排序。

如果输入为"Z"或"z",则必须将数组从Z到A进行排序。

如果输入为"R"或"r",则必须对数组进行反转。

该数组是一个字符串数组。

因此,我想知道使用switch case是否更有效率。

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 (choice.ToLower() == "a" || choice.ToLower() == "z")
 {
     Array.Sort(array);
 }

 if (choice.ToLower() == "r" || choice.ToLower() == "z")
 {
     Array.Reverse(array);
 }

而且,如果这段代码能进一步优化,那么怎么做呢。

所以,使用switch case结构还是像上面那样使用if结构方式最有效?请解释原因。

我很好奇,因为我总是试图将我的所有代码都最大限度地优化。


2
第一个更有效率,因为它只调用一次ToLower方法。但是它们都编译为 if-else 语句。在使用 switch 的编译代码中,choice.ToLower() 被保存在本地变量中,并且其值在 if-else 语句中被检查。然而,第二个版本有可能会从1到4次调用ToLower方法。 - M.kazem Akhgary
1
如果您也关心速度,那么直接按相反顺序排序比排序后再反转要快。 - Sami Kuhmonen
你尝试过对其进行基准测试吗? - rhens
如果我在执行代码之前将choice.ToLower存储在choice中,然后在if结构中省略ToLower,那么执行速度会更快吗? - Jesse Verbruggen
@Claies,我们已经讨论过switch case的问题了,本次练习的重点是显示数组。但是老师暗示可以使用switch case,但我想看看我的想法是否更好。 - Jesse Verbruggen
显示剩余2条评论
3个回答

6

好的,您可以自行检查:

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);
    }
}

正如您所看到的,结果几乎完全相同:
1010 ms    vs    1008 ms

这段代码非常有帮助,谢谢。当我在if结构中更改choice.ToLower,使其只被调用一次时,我的结果为:1749毫秒 vs 1694毫秒。 - Jesse Verbruggen
@JesseVerbruggen 没问题。随意尝试这个简单的基准测试来测试性能... 此外,正如其他人所说,ToUpper()ToLower()更好。我建议99%的时间执行这两种方法是为了Sort()Reverse()方法,而不是ifswitch语句。 - Fabjan

1

使用 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));
    }
}

在 switch 语句中添加默认值是否比不添加更好?因为当输入不是 a、z 或 r 时,什么也不需要做。 - Jesse Verbruggen
1
推荐:https://dev59.com/hm445IYBdhLWcg3w5OEH - Matěj Pokorný

0

在你的情况下,它会变慢,因为每次都要检查两个条件。请参考文章关于switchif速度的比较(在你的例子中,if的4个条件总是被检查)。
如果一个switch包含超过五个元素,则使用查找表或哈希列表实现,这意味着所有项目具有相同的访问时间,而不是if列表,其中最后一个项目需要更长的时间才能到达,因为它必须首先评估每个先前的条件。


1
这不是很清晰。字符串的 switch 语句使用哈希表,可能会更慢。 - usr
@usr 我已经在我的答案中包含了这个案例。 - CDrosos
这是真的,实际上,因为他的情况少于五个条件。我没有注意到那个。 - usr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接