【问题标题】:How to reduce the memory usage of a C# console application project?如何减少 C# 控制台应用程序项目的内存使用量?
【发布时间】:2016-04-18 17:26:58
【问题描述】:

这是程序消耗 36.50 MB 的内存,但我希望它小于 32 MB

public static void CreateText(string text)
{
    if (Convert.ToInt32(text.Length) <= 80)
    {
        int n;
        string str = "";
        string count = "";
        char[] mas = text.ToCharArray();

        for (int i = 0; i < Convert.ToInt32(mas.Length); i++)
        {
            if (int.TryParse(mas[i].ToString(), out n))
            {
                count += mas[i].ToString();
            }
            else
            {
                if (String.IsNullOrEmpty(count))
                {
                    str += mas[i].ToString();
                }
                else
                {
                    for (int j = 0; j < Convert.ToInt32(count); j++)
                    {
                        str += mas[i].ToString();
                    }
                    count = "";
                }
            }

        }
        Console.WriteLine(str);
    } else {
        Console.WriteLine("Error");
    }
}

【问题讨论】:

  • 为什么是Convert.ToInt32(text.Length)text.Length 已经是 INT 类型
  • 内存不够
  • 也许字符串生成器可以救你
  • 这似乎......随意。您在这里的确切目标是什么?
  • 另外...我不确定count += mas[i].ToString(); 行是否符合您的预期。

标签: c# memory


【解决方案1】:

为了减少内存占用,您需要读取通过对字符串应用操作+= 生成的临时字符串对象。 String 是 C# 中的不可变对象,因此 += 创建新字符串。 StringBuilder 是可变的,所以用它来代替字符串。您还需要将 count 作为 int,而不是 string 或 StringBuilder。

public static void CreateText(string mas)
{
    if (mas.Length <= 80)
    {
        StringBuilder str;
        int count;
        for (int i = 0; i < mas.Length; i++)
        {
            if (mas[i] >= '0' && mas[i] <= '9')
                count = count * 10 + mas[i] - '0';
            else
            {
                if (count == 0)
                    str.Append(mas[i]);
                else
                {
                    for (int j = 0; j < count; j++)
                          str.Append(mas[i]);
                    count = 0;
                }
            }
        }
        Console.WriteLine(str.ToString());
    }
    else
        Console.WriteLine("Error");
}

【讨论】:

  • 您能否添加一些文字来解释您所做的更改以及为什么它会降低内存要求?这将使这是一个更好的答案。
  • 您不妨将int.TryParse(mas[i].ToString(), out n) 替换为'0' &lt;= text[i] &amp;&amp; text[i] &lt;= '9'n = text[i] - '0'。完全跳过mas,改为索引text
  • 甚至需要mas 变量吗? C#中不能直接索引字符串吗?
  • 所以,错误 1 ​​'int' 不包含 'Append' 的定义,并且找不到接受第一个类型为 'int' 的参数的扩展方法 'Append'(您是否缺少 using 指令还是程序集参考?
  • count += (mas[i] - '0'); 语句不再像以前那样做。现在这是将各个数字相加,而不是形成字符串的 int 等价物。应该类似于count *= 10 + (mas[i] - '0');
【解决方案2】:

这可能是不可能的。 36MB 程序中的大部分 RAM 只是核心框架库。 36MB 没什么

但我确实看到了一些潜在的改进,其中最大的是将count 维护为 integer 而不是字符串,并使用字符串构造函数和 StringBuilder 而不是一直附加到字符串:

public static void CreateText(string text)
{
    if (text != null && text.Length <= 80)
    {
        int n; int count = 0;
        StringBuilder result = new StringBuilder();
        char[] mas = text.ToCharArray();

        foreach(char c in text)
        {
            if (int.TryParse(c.ToString(), out n))
            {
                count = (count * 10) + n;
            }
            else
            {
                if (count == 0) 
                { 
                    result.Append(c);
                }
                else
                {
                    result.Append(new string(c, count));
                    count = 0;
                }
            }

        }
        Console.WriteLine(result.ToString());
    } else {
        Console.WriteLine("Error");
    }
}

如果您希望能够在输入字符串中显式设置 0 重复,则存在一个潜在的错误。如果是这种情况,我们将需要一些效率稍低的东西,但应该仍然比原来有很大的改进:

public static void CreateText(string text)
{
    if (text != null && text.Length <= 80)
    {
        int n; int count = -1;
        StringBuilder result = new StringBuilder();
        char[] mas = text.ToCharArray();

        foreach(char c in text)
        {
            if (int.TryParse(c.ToString(), out n))
            {
                if (count == -1) count = 0;
                count = (count * 10) + n;
            }
            else
            {
                if (count == -1) 
                { 
                    result.Append(c);
                }
                else
                {
                    result.Append(new string(c, count));
                    count = -1;
                }
            }

        }
        Console.WriteLine(result.ToString());
    } else {
        Console.WriteLine("Error");
    }
}

【讨论】:

  • woooowww 是的工作 100% ...内存 15MB 非常感谢!
【解决方案3】:

试试这个:

public static void CreateText(string text)
{
    if (text.Length <= 80)
    {
        var str = new StringBuilder();
        var count = new StringBuilder();

        for (int i = 0; i < text.Length; i++)
        {
            int n;
            if (int.TryParse(text[i].ToString(), out n))
            {
                count.Append(text[i]);
            }
            else
            {
                if (String.IsNullOrEmpty(count.ToString()))
                {
                    str.Append(text[i]);
                }
                else
                {
                    for (int j = 0; j < Convert.ToInt32(count.ToString()); j++)
                    {
                        str.Append(text[i].ToString());
                    }
                    count.Clear();
                }
            }
        }
        Console.WriteLine(str);
    }
    else
    {
        Console.WriteLine("Error");
    }
}

我所做的是:

【讨论】:

  • 你能给我一个输入和输出的例子吗?你遇到了什么错误?
  • 输入:3A4B -----输出:AAABBBB
  • ERROR______mscorlib.dll 中出现“System.InvalidCastException”类型的未处理异常附加信息:无法将“System.Text.StringBuilder”类型的对象转换为“System.IConvertible”类型。
  • 移动 n 对于许多输入可能会更糟,因为它现在在每个循环中都是一个单独的变量......尽管我希望编译器会优化掉差异。
  • @TaGiAsadullazadeh 我做了一些更新。在我的机器上,它位于18.8MB(即发布版本)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-09-28
  • 2020-12-24
  • 2012-06-20
  • 2018-03-06
  • 2010-10-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多