c#加载文件所用的时间

时间:2011-07-13 12:18:08

标签: c# file

我发现将文件“加载”到文件中可能需要非常不同的时间 - 即使我的机器似乎没有做太多其他事情。我附上了一些代码来说明问题:

输出低于。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Runtime.InteropServices;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            LoadFileUnman();
            LoadFileUnman();
            LoadFileUnman();
            LoadFileUnman();
            LoadFileUnman();
            Console.WriteLine("Done");
        }

        public unsafe bool LoadFileUnman()
        { 
            string filename = @"C:\DataFile.BNF";

            var fileStream = new FileStream(filename,
                  FileMode.Open,
                  FileAccess.Read,
                  FileShare.Read,
                  16 * 1024,
                  FileOptions.SequentialScan);

            if (fileStream == null)
            {
                Console.WriteLine( "Could not open file");
                return true;
            }

            Int64 length = fileStream.Length;
            Console.WriteLine("File length: " + length.ToString("#,###"));

            UnmanagedMemoryStream GlobalMS;
            IntPtr GlobalBuffer;

            try
            {
                IntPtr myp = new IntPtr(length);
                GlobalBuffer = Marshal.AllocHGlobal(myp);
            }
            catch (Exception er)
            {
                Console.WriteLine("Could not allocate memory: " + er.Message);
                return true;
            }


            unsafe
            {

                byte* pBytes = (byte*)GlobalBuffer.ToPointer();
                GlobalMS = new UnmanagedMemoryStream(pBytes, (long)length, (long)length, FileAccess.ReadWrite);
                DateTime befDT = DateTime.Now;
                fileStream.CopyTo(GlobalMS);
                Console.WriteLine("Load took: " + DateTime.Now.Subtract(befDT).TotalMilliseconds.ToString("#,###") + "ms");
                GlobalMS.Seek(0, SeekOrigin.Begin);

            }


            GlobalMS.Close();
            fileStream.Close();


            return false;

        }

    }
}

这是输出,当我使用更大的文件(10G)时,时间差异更大。然后有时加载甚至一分钟都是几秒钟。

File length: 178,782,404
Load took: 5,125ms
File length: 178,782,404
Load took: 156ms
File length: 178,782,404
Load took: 172ms
File length: 178,782,404
Load took: 141ms
File length: 178,782,404
Load took: 1,891ms

任何人都可以告诉我它为何如此变数,如果有什么我可以做的。

EDIT 1

从我的评论中 - 对我来说似乎是一个好主意,强调我需要的是一种方法来修复负载的可变性而不是整体速度。我可以通过优化方式(我有)来提高速度,但这是问题的结果加载时间的差异。

EDIT 2

以下是我正在运行的服务。如果有人注意到任何可能导致我问题的人,我将不胜感激。

enter image description here

4 个答案:

答案 0 :(得分:3)

这取决于很多因素,例如你当时PC正在做什么,磁盘碎片,内存是否(几乎)满等等。

除了优化您的环境之外,您无能为力:

  1. 快速获取硬盘。
  2. 定期优化硬盘(即碎片整理)。
  3. 减少PC上的负载 - 删除所有不需要的软件和服务。
  4. 如果您的足迹超过75%,请增加记忆力。
  5. 如果您阅读的文件是副本,那么您可以从RAM磁盘中读取它们 - 因此您可能有一个后台进程将文件复制到RAM磁盘,然后您的程序可以从那里读取它们。这也比从磁盘读取速度快得多。

    另请参阅http://www.softperfect.com/products/ramdisk/了解RAM磁盘软件。

    编辑:从你的图片中我注意到以下内容,这可能会影响性能(注意这个列表并非详尽无遗,因此可能还有其他我没注意到的服务导致延迟):

    • Google软件更新程序 - 不确定,但可能会导致延迟
    • 转到我的电脑 - 你确定没有人登录机器并做一些会降低你电脑速度的东西吗?
    • LiveShare P2P服务器 - 再次,如果有人连接到您的PC下载内容,那将导致性能变化
    • SQL Server Express - 如果正在查询,则会导致严重的可变性。

答案 1 :(得分:1)

需要考虑的事项:

  1. 磁盘缓存。 Windows将使用大部分可用内存来缓存您已阅读的文件。这会给你一个初始惩罚,然后是高速。加载任何其他内容可能会从内存中弹出您的文件。内存分配可能会弹出您的文件。 (因此,当您分配了足够的内存时,它将删除缓存的文件。)
  2. 要将数据放入内存,Windows需要释放内存。这需要一些时间(在内存较少的10GB文件的情况下)可能需要在磁盘上分配空间。
  3. 释放内存时,Windows必须将其清除,以便可以重复使用。如果是大文件,则会对磁盘执行此操作。
  4. Windows将缓冲写入操作。释放大量内存会导致大量擦除。这不是马上就完成的。
  5. 当你谈论毫秒时,磁盘上正在发生的其他事情会影响结果...一个搜索单独吃了一把ms,所以当你测试smallscale时任何小的写操作都会影响结果(测试在当前形式下无效。)
  6. 各种“正常”因素,如磁盘碎片。
  7. 如果你跑了5次以上就会看到结果会很有趣。

    其他一些信息:
    等待磁盘的IO绑定进程将优先提升,以便能够立即处理数据。大多数操作系统都将其作为调度程序架构的一部分。这意味着通常一个中等繁忙的系统不应该对正在运行的进程产生很大影响......除非它们共享一些缓慢的设备。磁盘是一个很慢的设备,但很容易忘记内存也是一个相对较慢的设备,应该小心共享。

    对于并列论(假设你正在编写服务器软件):我的MSSQL服务器有数据库/日志有效地分布在28个磁盘上,服务器包含几个带有多个CPU的卡,所有这些卡都有单独的总线访问单独的内存,还有一些交叉连接。 MSSQL利用它将部分DB分配给与最近的CPU对应的内存。搜索在所有CPU及其关闭内存上并行完成(请参阅NUMA。我的观点是有专门用于推动类似场景的硬件。

答案 2 :(得分:0)

第一次实例化缓冲区时,操作系统会搜索空闲内存。对于10G文件,很明显必须在磁盘上找到空间,因此存在巨大的延迟。再次重做任务后,内存在回收之前仍然可用。

您可以通过在按钮处理程序中的每个LoadFileUnman()之后放置一个GC.Collect()来验证这一点。

答案 3 :(得分:0)

退房 http://social.technet.microsoft.com/Forums/en/winservergen/thread/09c80df1-4bd4-4400-bcaf-cec892a0626a

Windows系统正在幕后做事,这使得“无法”控制或测试真正发生的事情。 Windows系统在其他所有内容上都有自己的缓冲层。文件流刷新不会将数据刷新到磁盘,而是刷新系统,它可以根据需要执行所需的操作。

请参阅可从任务管理器启动的资源监视器,然后您可能会看到系统进程正在读取和写入与您的应用程序相同的文件。

- 我想要的是大文件的最佳顺序读写速度,但是由于这样的智能系统以及“优秀的”ms文档,我真的被卡住了。猜猜我会像其他人一样做,无论做什么都有效......悲伤的事情