c # Время, необходимое для загрузки файла - PullRequest
2 голосов
/ 13 июля 2011

Я обнаружил, что "загрузка" файла в память может занимать очень много времени - даже если моя машина, кажется, больше ничего не делает. Я приложил некоторый код, чтобы проиллюстрировать проблему:

Выход ниже.

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 ]

3 голосов
/ 13 июля 2011

Это зависит от многих факторов, таких как то, что еще ваш компьютер делает в данный момент, фрагментация диска, заполнена ли память (почти) и т. Д.

На самом деле вам не так многоможет сделать, кроме оптимизации вашей среды:

  1. Получите быстрые жесткие диски.
  2. Регулярно оптимизируйте жесткие диски (т.е. дефрагментируйте).
  3. Уменьшите нагрузку на ПК- удалите все ненужные программы, сервисы.
  4. Увеличьте объем памяти, если размер вашего отпечатка превысит 75%.

Если прочитанные файлы являются копиями, вы можете прочитать их из ОЗУдиск - так что у вас может быть фоновый процесс, который копирует файлы на RAM-диск, и тогда ваша программа может читать их оттуда.Это также значительно быстрее, чем чтение с диска.

См. Также http://www.softperfect.com/products/ramdisk/ для программного обеспечения RAM-диска.

РЕДАКТИРОВАТЬ: На вашем изображении я заметил следующее, что может повлиять на производительность (обратите внимание, что этот список не является исчерпывающим, поэтому могут быть другие службы, которые я не заметил, которые вызывают задержки):

  • Google Software Updater - Не уверен, но это может вызвать задержки
  • Goto My PC - Вы уверены, что никто не входит в компьютер и не делает что-то, что замедляет ваш компьютер?
  • LiveShare P2P Server - Опять же, если есть люди, подключающиеся к вашему ПК для загрузки материала, это будетвызывает изменчивость производительности
  • SQL Server Express - при запросе вызывает серьезную изменчивость.
1 голос
/ 13 июля 2011

Что нужно учитывать:

  1. Кэширование диска. Windows будет использовать большую часть доступной памяти для кэширования прочитанных вами файлов. Это дает вам начальный штрафной удар, а затем высокую скорость. Все, что загружено, может удалить ваш файл из памяти. Распределение памяти может вытолкнуть ваши файлы. (Таким образом, если вы выделите достаточно памяти, кешированный файл будет удален.)
  2. Чтобы поместить ваши данные в память, Windows необходимо освободить память. Это займет время, так как (в случае файла 10 ГБ с меньшим объемом ОЗУ) может потребоваться выделить место на диске.
  3. Когда вы освобождаете память, Windows должна очистить ее, чтобы она была готова для повторного использования. В случае большого файла это делается на диск.
  4. Windows буферизует операции записи. Освобождение большого количества памяти приведет к очереди большого количества очистки. Это не сделано немедленно iirc.
  5. Другие вещи, происходящие на диске, будут влиять на результат LOT, когда вы говорите о миллисекундах ... Один запрос поиска потребляет несколько мсек, поэтому любая маленькая операция записи во время тестирования мелкой шкалы повлияет на результат ( тест просто недействителен в его текущей форме).
  6. Различные "нормальные" факторы, такие как фрагментация диска.

Было бы интересно увидеть результаты, если вы запустили это более 5 раз.

Некоторая дополнительная информация:
Привязанный к IO процесс, ожидающий диска, будет увеличен в приоритетном порядке, чтобы он мог обрабатывать данные немедленно. Большинство ОС делают это как часть своей архитектуры планировщика. Это означает, что обычно умеренно загруженная система не должна сильно влиять на выполняемый процесс ... если только они не используют какое-то медленное устройство. Диск - это медленное устройство, но легко забыть, что память - это относительно медленное устройство, и с ним следует обращаться осторожно.

Для паралеллизма (при условии, что вы пишете серверное программное обеспечение): Мой MSSQL-сервер имеет БД / журнал, эффективно распределенный по 28 дискам, и сервер содержит несколько карт с несколькими ЦП, все с отдельным доступом к шине к отдельной памяти, а также некоторые перекрестные соединения. MSSQL использует это для выделения частей БД в памяти, соответствующих ближайшему ЦП. Поиск выполняется параллельно на всех процессорах + их закрывающая память (см. NUMA . Я хочу сказать, что есть оборудование, специально разработанное для ускорения подобных сценариев.

0 голосов
/ 26 июля 2011

Выезд http://social.technet.microsoft.com/Forums/en/winservergen/thread/09c80df1-4bd4-4400-bcaf-cec892a0626a

Система Windows делает что-то за кулисами, что делает «невозможным» контроль или тестирование того, что действительно происходит. Система Windows имеет свой собственный слой буферизации поверх всего остального. Сброс файлового потока не сбрасывает данные на диск, а скорее в систему win, которая делает то, что хочет и когда хочет.

См. Монитор ресурсов, который можно запустить из диспетчера задач, затем вы можете увидеть, как системный процесс читает и записывает в тот же файл, что и ваше приложение.

-Все, что я хочу, это лучшая скорость последовательного чтения и записи больших файлов, но благодаря такой умной системе и «превосходной» документации MS я действительно застрял. Думаю, я сделаю так же, как и все остальные, - что бы ни работало ... Грустная вещь

0 голосов
/ 13 июля 2011

При первом создании буфера ОС ищет свободную память.Для файла 10G ясно, что на диске должно быть место, таким образом огромная задержка.После повторного выполнения задачи память остается доступной до ее восстановления.

Возможно, вы можете убедиться в этом, поместив GC.Collect () после каждого LoadFileUnman () в обработчик кнопки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...