C#文件I / O效率

时间:2009-11-19 23:14:35

标签: c# performance file-io

我做了一个家庭作业,这是问题陈述:

您的计划应如下工作:

  1. 要求用户提供文件名。获取文件名并保存。
  2. 打开文件。
  3. 从文件中读取温度和风速。这两个值都应存储在声明为double的变量中。该文件是文本文件。文件的每一行都包含温度和风速值。
  4. 使用程序员编写的方法计算风寒因子,并以下列形式显示结果:

    对于t =来自文件的温度   和v =来自文件的风速   风寒指数=计算结果华氏度。

    显示小数点后两位数的所有数字。 (记住 - 没有神奇的数字!)

  5. 重复这些步骤,直到遇到文件结尾。

  6. 我已经完成了作业,我的代码在下面,我只是想知道是否有任何方法可以提高效率,或者如果有一些不同的创造性方法来解决这个问题,我已经把它转过来了50/50,但我很好奇你们有些高级和熟练的程序员会如何解决这个问题。

    using System;
    using System.IO;
    
    class Program
    {
        // declare constants to use in wind chill factor equation - no magic numbers
        const double FIRST_EQUATION_NUMBER = 35.74;
        const double SECOND_EQUATION_NUMBER = 0.6215;
        const double THIRD_EQUATION_NUMBER = 35.75;
        const double FOURTH_EQUATION_NUMBER = 0.4275;
        const double EQUATION_EXPONENT = 0.16;
        const int DEGREE_SYMBOL_NUMBER = 176;
    
        static void Main()
        {
            // declare and initialize some variables
            string filePath = "";
            string line = "";
            double temperature = 0.0;
            double windSpeed = 0.0;
            double windChillFactor = 0.0;
            char degreeSymbol = (char)DEGREE_SYMBOL_NUMBER;
    
            // ask user for a file path
            Console.Write("Please enter a valid file path: ");
            filePath = Console.ReadLine();
    
            // create a new instance of the StreamReader class
            StreamReader windChillDoc = new StreamReader(@filePath);
    
            // start the read loop
            do 
            {
                // read in a line and save it as a string variable
                line = windChillDoc.ReadLine();
    
                // is resulting string empty? If not, continue execution
                if (line != null)
                {
                    string[] values = line.Split();
                    temperature = double.Parse(values[0]);
                    windSpeed = double.Parse(values[1]);
    
                    windChillFactor = WindChillCalc(temperature, windSpeed);
    
                    Console.WriteLine("\nFor a temperature {0:f2} F{1}", temperature, degreeSymbol);
                    Console.WriteLine("and a wind velocity {0:f2}mph", windSpeed);
                    Console.WriteLine("The wind chill factor = {0:f2}{1}\n", windChillFactor, degreeSymbol);
                }
            } while (line != null);
    
            windChillDoc.Close();
    
            Console.WriteLine("\nReached the end of the file, press enter to exit this program");
    
            Console.ReadLine();
        }//End Main()
    
        /// <summary>
        /// The WindChillCalc Method
        /// Evaluates a wind chill factor at a given temperature and windspeed
        /// </summary>
        /// <param name="temperature">A given temperature</param>
        /// <param name="ws">A given windspeed</param>
        /// <returns>The calculated wind chill factor, as a double</returns>
        static double WindChillCalc(double temperature, double ws)
        {
            double wci = 0.0;
            wci = FIRST_EQUATION_NUMBER + (SECOND_EQUATION_NUMBER * temperature) - (THIRD_EQUATION_NUMBER * (Math.Pow(ws, EQUATION_EXPONENT))) + (FOURTH_EQUATION_NUMBER * temperature * (Math.Pow(ws, EQUATION_EXPONENT)));
            return wci;
        }
    }//End class Program 
    

    随时告诉我你的想法。

9 个答案:

答案 0 :(得分:9)

你的方式很好,但是:

  • 如果你使用PascalCase作为常量会更好看,因为这是c#使用的编码约定。
  • 你应该将StreamReader包装在using语句中,这样一旦你完成它就会被妥善处理。
  • 您可能还应该将其包装在try块中(以及正确处理异常的catch)以确保您没有获得FileNotFound异常。
  • 以下列方式构建while循环可能是个更好的主意:

while((line = windChillDoc.ReadLine()) != null) { ... } [Darn格式化无效!]

除此之外,我不知道因为我不熟悉天气计算:)

答案 1 :(得分:7)

你不会比C#中的文件IO获得更多的zippier。根据数据集的大小,使用缓冲读取器可能是值得的,但对于足够小的文件,它是不值得的。我会按原样离开。

答案 2 :(得分:6)

你的大部分评论都是无关紧要的。 The code should tell you how...the comments should tell you why.

答案 3 :(得分:6)

轻微的挑剔,但如果你使用的是英文方法名称,那么“WindChillCalc”应该是“CalcWindChill”(动词先行)。

答案 4 :(得分:5)

string filePath = "";
...
filePath = Console.ReadLine();

不要使用从未使用过的值进行初始化;并保持声明和初始化紧密结合:

string filePath = Console.ReadLine();

已提及

using - 但不要不必要地使用@

new StreamReader(@filePath);

应该只是:

new StreamReader(filePath);

就个人而言,我会使用LINQ作为读卡器,但那只是我; -p

答案 5 :(得分:4)

为什么执行/而?在 do 中,检查是否为null。在 while 中,检查是否为null。为什么不把它作为 while 语句?

string line;
while((line = windChillDoc.ReadLine()) != null)
{
    //Logic
}

编辑:修正了编译错误。有趣的是我最初有这个。这个富文本框需要一个编译器! :P

答案 6 :(得分:3)

虽然与性能无关(主要问题)

IMO:

const double FIRST_EQUATION_NUMBER = 35.74;
const double SECOND_EQUATION_NUMBER = 0.6215;
const double THIRD_EQUATION_NUMBER = 35.75;
const double FOURTH_EQUATION_NUMBER = 0.4275;
const double EQUATION_EXPONENT = 0.16;

并不比魔术数字好多少。看着我不知道FIRST_EQUATION_NUMBER除了在某个方程中使用的是什么,我不知道它们是在同一个等式中还是你有四个使用不同数字的等式?它们也可以被放入实际的方法中,因为它们是唯一使用它们的地方。

我会将degreeSymbol更改为const而不是使用const int 后面。

const char DEGREE_SYMBOL = (char)176;

答案 7 :(得分:2)

如果你在风格等方面得到了标记,那么就会有一些非常小的东西

  • 将双精度初始化为0.0是多余的。
  • string.Empty是首选而不是“”
  • 您的windchill方法可以简单地更改(但是,在编译期间,我认为wci将被优化 - 所以它在功能上是相同的):

(更改了SO可读性的格式)

static double WindChillCalc(double temperature, double ws)
{
    return FIRST_EQUATION_NUMBER + 
        (SECOND_EQUATION_NUMBER * temperature) - 
        (THIRD_EQUATION_NUMBER * (Math.Pow(ws, EQUATION_EXPONENT))) + 
        (FOURTH_EQUATION_NUMBER * temperature * (Math.Pow(ws, EQUATION_EXPONENT)));
}

答案 8 :(得分:0)

在这样的小型学术课程中,除非你做一些非常愚蠢的事情,否则表现不会成为问题。判断性能是否成问题的简单方法是提出一个问题:“这会让我等待吗?”

如果有大量的输入,我会问谁在提供输入以及谁在阅读输出。这会告诉我是否可以用二进制而不是文本来进行I / O,因为实际上,到目前为止,大部分处理将是在输入时将文本转换为数字,在输出时将数字转换为文本,尤其是浮点。