История: у меня есть большой XML файл размером более 70 ГБ, который мне нужно анализировать в базе данных один раз в неделю. В настоящее время у меня есть рабочий синтаксический анализатор в VB. net с использованием XmlReader. В настоящее время я достигаю максимума в 5.000 узлов / с c и с> 10.000.000 узлов и растущими, это требует времени для завершения. Программа работает на моем собственном сервере в гараже с обычным SSD. Я предположил, что ограничивающим фактором был SSD, поэтому недавно я перешел на Samsung EVO 970 M.2 SSD с увеличенной в 6 раз скоростью чтения / записи. Проблема в том, что я не увидел заметного увеличения производительности. Оглядываясь назад, вероятно, очевидно, что узкое место где-то еще ..
Идея: я начал расследование. Я реализовал 2 отдельных потока, каждый из которых считывал файл с начала, с интервалом в несколько секунд. Каждый поток все еще считывал и обрабатывал около 5000 узлов / сек c, поэтому теперь я эффективно обрабатывал 10.000 узлов / сек c Однако проблема заключалась в том, что я дважды анализировал каждый узел, что отчасти устранило цель. Следующая идея была для одного потока, чтобы прочитать + обработать данные с самого начала. Второй поток также считывает данные с начала файла, однако этот поток просто пропускает первую половину файла, прежде чем он начнет обработку данных. Используя XMLReader.ReadToNextSibling (), я смог «пропустить» 6,250,000 узлов со скоростью 10000 узлов / сек c. По сути, это означает, что первый поток обработал бы около 3,125,000 узлов к тому времени, когда второй поток завершит «пропуск» и начнет анализировать с 6,250,000 узлов. На этом этапе между 6,875,000 узлов будет разбито. 2 потока и парсер будет с этого момента обрабатывать около 10.000 узлов / сек c. По сути, я хотел бы увеличить потоки, пока не достигну другого узкого места. Этот подход очень примитивен и «тратит» много времени на чтение и пропуск тех же узлов. Я попытался XmlReaderSettings.LineNumberOffset, однако я не мог заставить это работать, и это всегда, казалось, читало с начала независимо от смещения.
Dim settings = New Xml.XmlReaderSettings()
settings.LineNumberOffset = 100000
Dim XMLReader = Xml.XmlReader.Create("C:\largexml.xml", settings)
Вопрос: Любые идеи параллельного чтения больших файлов XML и возможные узкие места или оптимизации. Есть ли более быстрый способ "пропустить" n элементов, чем использовать ReadToNextSibling, как это?
Dim Count As Integer = 0
While Count < 5000000
XMLReader.ReadToNextSibling("ns")
Count += 1
End While
Я провел некоторые расчеты текущего решения "пропустить", и, поскольку мне приходится читать те же данные в каждый поток, то бонус скорости асимптотически c до + 50% ускорения. Вот график на случай, если у кого-то возникнет такая же проблема, и он рассматривает подобное наивное решение. Вот ожидаемое увеличение производительности / поток.