c#如何更快地运行应用程序

时间:2015-05-08 14:46:52

标签: c# performance

我正在创建一个可能的大写字母的单词列表,以证明这个代码将aaaaaaaa aaaaaaa写入aaaaaaa到aaaaaaa等不安全的8位密码,直到zzzzzzzz使用此代码:

class Program
{
    static string path;
    static int file = 0;
    static void Main(string[] args)
    {
        new_file();
        var alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456789+-*_!$£^=<>§°ÖÄÜöäü.;:,?{}[]";
        var q = alphabet.Select(x => x.ToString());
        int size = 3;
        int counter = 0;

        for (int i = 0; i < size - 1; i++)
        {
            q = q.SelectMany(x => alphabet, (x, y) => x + y);
        }
        foreach (var item in q)
        {
            if (counter >= 20000000)
            {
                new_file();
                counter = 0;
            }
            if (File.Exists(path))
            {
                using (StreamWriter sw = File.AppendText(path))
                {
                    sw.WriteLine(item);
                    Console.WriteLine(item);
                    /*if (!(Regex.IsMatch(item, @"(.)\1")))
                    {
                        sw.WriteLine(item);
                        counter++;
                    }
                    else
                    {
                        Console.WriteLine(item);
                    }*/
                }
            }
            else
            {
                new_file();
            }
        }
    }

    static void new_file()
    {
        path = @"C:\" + "list" + file + ".txt";
        if (!File.Exists(path))
        {
            using (StreamWriter sw = File.CreateText(path))
            {
            }
        }
        file++;
    }
}

“守则”工作正常,但运行它需要几周时间。有谁知道加速它的方法或我必须等待?如果有人有想法请告诉我。

3 个答案:

答案 0 :(得分:3)

性能:

size 3:   0.02s
size 4:   1.61s
size 5: 144.76s

提示:

  • 删除了LINQ以进行组合生成
  • 删除了每个密码的Console.WriteLine
  • 删除了StreamWriter
  • 用于文件写入的大缓冲区(128k)
  const string alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456789+-*_!$£^=<>§°ÖÄÜöäü.;:,?{}[]";
  var byteAlphabet = alphabet.Select(ch => (byte)ch).ToArray();
  var alphabetLength = alphabet.Length;

  var newLine = new[] { (byte)'\r', (byte)'\n' };

  const int size = 4;
  var number = new byte[size];
  var password = Enumerable.Range(0, size).Select(i => byteAlphabet[0]).Concat(newLine).ToArray();

  var watcher = new System.Diagnostics.Stopwatch();
  watcher.Start();

  var isRunning = true;
  for (var counter = 0; isRunning; counter++)
  {
    Console.Write("{0}: ", counter);
    Console.Write(password.Select(b => (char)b).ToArray());
    using (var file = System.IO.File.Create(string.Format(@"list.{0:D5}.txt", counter), 2 << 16))
    {
      for (var i = 0; i < 2000000; ++i)
      {
        file.Write(password, 0, password.Length);
        var j = size - 1;
        for (; j >= 0; j--)
        {
          if (number[j] < alphabetLength - 1)
          {
            password[j] = byteAlphabet[++number[j]];
            break;
          }
          else
          {
            number[j] = 0;
            password[j] = byteAlphabet[0];
          }
        }
        if (j < 0)
        {
          isRunning = false;
          break;
        }
      }
    }
  }
  watcher.Stop();
  Console.WriteLine(watcher.Elapsed);
}

答案 1 :(得分:1)

尝试以下修改后的代码。在LINQPad中,它运行于&lt; 1秒。使用原始代码,我在40秒后放弃了。它消除了为每个WriteLine操作打开和关闭文件的开销。您需要测试并确保其提供相同的结果,因为我不愿意在24小时内运行原始代码以确保输出相同。

class Program
{
    static string path;
    static int file = 0;
    static void Main(string[] args)
    {
        new_file();
        var alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456789+-*_!$£^=<>§°ÖÄÜöäü.;:,?{}[]";
        var q = alphabet.Select(x => x.ToString());
        int size = 3;
        int counter = 0;

        for (int i = 0; i < size - 1; i++)
        {
            q = q.SelectMany(x => alphabet, (x, y) => x + y);
        }

        StreamWriter sw = File.AppendText(path);

        try
        {
            foreach (var item in q)
            {
                if (counter >= 20000000)
                {
                    sw.Dispose();
                    new_file();
                    counter = 0;
                }
                sw.WriteLine(item);
                Console.WriteLine(item);
            }
        }
        finally
        {
            if(sw != null)
            {
                sw.Dispose();
            }
        }
    }

    static void new_file()
    {
        path = @"C:\temp\list" + file + ".txt";
        if (!File.Exists(path))
        {
            using (StreamWriter sw = File.CreateText(path))
            {
            }
        }
        file++;
    }
}

答案 2 :(得分:-2)

你的字母缺少0

修复后,你的套装中会有89个字符。为简单起见,我们称之为100。您要查找的集合是从该集合中提取的所有 8个字符长度字符串。其中有100 ^ 8,即10,000,000,000,000,000。

它们将占用的磁盘空间取决于你如何编码它们,让我们慷慨 - 假设你使用包含这些字符的一些8位字符集,并且你没有放回车,所以一个字节每个字符,所以10,000,000,000,000,000字节= ~10 peta byes?

你有10 PB的磁盘吗? (10000 TB)?

[编辑]回应&#39;这不是答案&#39;:

最初的动机是创建列表?显示列表的大小。如果它已经实现,很难看出列表可以完成什么,即重现它比加载它更快。当然,通过生成列表可以做出的任何一点也可以通过简单地了解它的大小来实现,上面显示了如何解决它。

您的代码中存在大量低效问题,但如果您的问题是“我如何快速生成此列表并将其写入磁盘”?答案是&#39;你实际上不能&#39;。

[/编辑]