【问题标题】:How do I speed up folder generating for loops?如何加快文件夹生成循环?
【发布时间】:2016-03-07 12:02:44
【问题描述】:

所以我为大声笑创建了一些代码来玩我的学校服务器,我制作了一个文件夹生成器,它在每个 az 文件夹中创建文件夹 az,其中包含 5 层文件夹。当我运行程序时,它是 uubbberrr 慢但是我猜它可以完成工作。有什么办法可以加快速度吗?这是我的代码

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace Folder_Generator
{
    class Program
    {
        private const int MF_BYCOMMAND = 0x00000000;
        public const int SC_CLOSE = 0xF060;

        [DllImport("user32.dll")]
        public static extern int DeleteMenu(IntPtr hMenu, int nPosition, int wFlags);

        [DllImport("user32.dll")]
        private static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);

        [DllImport("kernel32.dll", ExactSpelling = true)]
        private static extern IntPtr GetConsoleWindow();

        static void Main(string[] args)
        {
            DeleteMenu(GetSystemMenu(GetConsoleWindow(), false), SC_CLOSE, MF_BYCOMMAND);

            string topFolder = @"C:\";
            string subName = System.IO.Path.Combine(topFolder, "Files");
            System.IO.Directory.CreateDirectory(subName);
            subName = @"C:\Files\";

            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine("============================================");
            Console.ResetColor();
            Console.ForegroundColor = ConsoleColor.Blue;
            Console.WriteLine("^             Folder Generator             ^");
            Console.WriteLine("^             by Pinga Muncher             ^");
            Console.ResetColor();
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine("^------------------------------------------^");
            Console.ResetColor();
            Console.ForegroundColor = ConsoleColor.Blue;
            Console.WriteLine("^       Enter Yes to Start Generating      ^");
            Console.WriteLine("^         Enter No to Exit Program         ^");
            Console.ResetColor();
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine("============================================");
            Console.ResetColor();
            Console.ForegroundColor = ConsoleColor.Green;

            Start:
            string userInput = Console.ReadLine();
            switch (inputSwitch(userInput))
            {
                case 0:
                    Console.WriteLine("Invalid Input, Enter Either (Yes/y) or (No/n)");
                    goto Start;
                case 1:
                    Console.WriteLine("Exiting Now");
                    System.Threading.Thread.Sleep(1500);
                    System.Environment.Exit(-1);
                    break;
                case 2:
                    for (int a = 1; a < 26; a++)
                    {
                        for (int b = 1; b < 26; b++)
                        {
                            for (int c = 1; c < 26; c++)
                            {
                                for (int d = 1; d < 26; d++)
                                {
                                    string pathName1 = System.IO.Path.Combine(subName, switcheroo(a), switcheroo(b), switcheroo(c), switcheroo(d));
                                    System.IO.Directory.CreateDirectory(pathName1);
                                    Extract("Folder_Generator", pathName1, "myFolder", "troll.png");
                                    Console.WriteLine("{0} - {1} - {2} - {3}", switcheroo(a), switcheroo(b), switcheroo(c), switcheroo(d));
                                }
                                string pathName2 = System.IO.Path.Combine(subName, switcheroo(a), switcheroo(b), switcheroo(c));
                                System.IO.Directory.CreateDirectory(pathName2);
                                Console.WriteLine("{0} - {1} - {2}", switcheroo(a), switcheroo(b), switcheroo(c));
                            }
                            string pathName3 = System.IO.Path.Combine(subName, switcheroo(a), switcheroo(b));
                            System.IO.Directory.CreateDirectory(pathName3);
                            Console.WriteLine("{0} - {1}", switcheroo(a), switcheroo(b));
                        }
                        string pathName4 = System.IO.Path.Combine(subName, switcheroo(a));
                        System.IO.Directory.CreateDirectory(pathName4);
                        Console.WriteLine(switcheroo(a));
                    }
                    break;
            }
            Console.WriteLine("->----<- The Files Have Been Made :) ->----<-");
            Console.ReadKey();
        }

        static int inputSwitch(string input)
        {
            string i = input;
            switch (i)
            {
                case "Yes":
                    return 2;
                case "yes":
                    return 2;
                case "y":
                    return 2;
                case "No":
                    return 1;
                case "no":
                    return 1;
                case "n":
                    return 1;
            }
            return 0;
        }

        static string switcheroo(int num)
        {
            int count = num;
            switch (count)
            {
                case 1:
                    return "a";
                case 2:
                    return "b";
                case 3:
                    return "c";
                case 4:
                    return "d";
                case 5:
                    return "e";
                case 6:
                    return "f";
                case 7:
                    return "g";
                case 8:
                    return "h";
                case 9:
                    return "i";
                case 10:
                    return "j";
                case 11:
                    return "k";
                case 12:
                    return "l";
                case 13:
                    return "m";
                case 14:
                    return "n";
                case 15:
                    return "o";
                case 16:
                    return "p";
                case 17:
                    return "q";
                case 18:
                    return "r";
                case 19:
                    return "s";
                case 20:
                    return "t";
                case 21:
                    return "u";
                case 22:
                    return "v";
                case 23:
                    return "w";
                case 24:
                    return "x";
                case 25:
                    return "y";
                case 26:
                    return "z";
            }
            return "a";
        }

        public static void Extract(string nameSpace, string outDirectory, string internalFilePath, string resourceName)
        {
            Assembly assembly = Assembly.GetCallingAssembly();

            using (Stream s = assembly.GetManifestResourceStream(nameSpace + "." + (internalFilePath == "" ? "" : internalFilePath + ".") + resourceName))
            using (BinaryReader r = new BinaryReader(s))
            using (FileStream fs = new FileStream(outDirectory + "\\" + resourceName, FileMode.OpenOrCreate))
            using (BinaryWriter w = new BinaryWriter(fs))
            {
                w.Write(r.ReadBytes((int)s.Length));
            }
        }
    }
}

【问题讨论】:

  • 这里没有多线程。您可以使用并行 for 循环,因为一旦创建了基础,其余的不需要按特定顺序发生。
  • 您正在尝试创建 26^4 或 456.976 个文件夹(这只是最内部的循环)。难怪它很慢。
  • ahhh my eyes...。说真的,虽然你没有多线程,这是一个主要的瓶颈。此外,您只需要 4 层深度(456,976 个文件夹),5 层深度将是 11,881,376。您可以用递归替换 4 for 循环以提高可读性。如果您摆脱 case 语句并使用数组,您将获得性能提升。最后,尽管您计划进行所有恶作剧,但只需一次快速操作即可删除整个文件夹树。
  • 如果代码正常运行,这似乎更适合codereview.stackexchange.com
  • 另外Console.WriteLine 也会对性能产生影响

标签: c# multithreading performance for-loop


【解决方案1】:

将此代码添加到您的代码中,然后调用 start(subName)。 我使用 CreateDirectory API 来提高速度,并且我正在创建并行工作的多任务。希望对您有所帮助。

[DllImport("kernel32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool CreateDirectory(string lpPathName, IntPtr lpSecurityAttributes);

static string[] chrs = new string[] { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" };

private static void start(string subName)
{
    Parallel.For(0, chrs.Length, a =>
    {
        createFolder(Path.Combine(subName, chrs[a]));
    });
}

private static void createFolder(string path)
{
    CreateDirectory(path, IntPtr.Zero);
    for (int b = 0; b < chrs.Length; b++)
    {
        string pathB = path + "\\" + chrs[b];
        CreateDirectory(pathB, IntPtr.Zero);
        for (int c = 0; c < chrs.Length; c++)
        {
            string pathC = pathB + "\\" + chrs[c];
            CreateDirectory(pathC, IntPtr.Zero);
            for (int d = 0; d < chrs.Length; d++)
            {
                string pathD = pathC + "\\" + chrs[d];
                CreateDirectory(pathD, IntPtr.Zero);
                Extract("Folder_Generator", pathD, "myFolder", "troll.png");
            }
        }
        Console.WriteLine(path + "\\" + chrs[b]);
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-08-20
    • 1970-01-01
    • 1970-01-01
    • 2019-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多