Как прочитать большой файл Excel, используя многопоточное программирование в Coldfusion/Lucee?

Я пытаюсь прочитать большой файл Excel с использованием 10 потоков, как показано в коде ниже:

<cfset var _Qry = 0 />

<cfloop from="1" to="10" index="idx">
    <cfthread name="Thread#idx#" action="run" src="#arguments._file#">                                      
           <cfspreadsheet 
                 action="read" 
                 src="#src#" 
                 sheet="1" 
                 query="_Qry" 
                 headerrow="1" 
                 excludeHeaderRow="true">
    </cfthread>
</cfloop>


<cfloop from="1" to="10" index="idx">
    <cfthread name="Thread#idx#" action="join" />               
</cfloop>

<cfdump var="#_Qry#">

Но когда я сбрасываю _Qry переменная не приводит к ожидаемому запросу, прочитанному из файла. Он выдает 0. Я подозреваю, что это проблема с областью потока или результатом слияния, с которой я не знаю, как обойтись.

Спасибо за вашу помощь:)

1 ответ

Многопоточность - это не решение каждой проблемы

Здесь есть несколько вопросов

1) Если у вас нет распределенной файловой системы, например, HDFS, это не очень хороший подход к проблеме. Только один поток может одновременно читать файл из стандартной файловой системы, и узким местом является файловая система, а не центральный процессор.

Для больших данных есть такие решения, как Hadoop, который содержит HDFS, и Apache Spark. Распределенные файловые системы, такие как HDFS, были специально разработаны для решения этой проблемы, так что вы можете читать огромные файлы параллельно, где вы читаете другую часть файла с отдельного узла с отдельного диска.

2) Ваш фрагмент кода "пытается" прочитать весь файл в каждой теме.

Это означает, что если бы у вас была распределенная файловая система, вы бы ничего не получили, потому что вы читаете весь файл с каждого узла. В обычной файловой системе это намного хуже - вы, вероятно, будете читать файл до 10 раз из-за узкого места, упомянутого выше.

Вероятно, это не будет полными 10 раз благодаря оптимизации и кешированию, которые использует большинство файловых систем, но это всегда будет медленнее, чем обычное чтение файла.

3) Когда вы звоните <cfthread query="_qry" ...> переменная _qry установлена ​​в локальную область потока и выходит из области, когда поток завершает свое выполнение.

Если вы хотите иметь доступ к нему после завершения потока, вам нужно установить для него THREAD Scope. Рассмотрим следующий пример:

<cfscript>
thread name="T1" {
  x = getTickCount();         // local scope in thread T1
  thread.y = round(x / 1000); // THREAD scope in thread T1
}

thread action="join";

dump(cfthread.T1.y);          // will show the value of y from thread T1

//     dump(cfthread.T1.x);   // error, does not exist
//     dump(x);               // error, does not exist, this is what you have
</cfscript>

Смотрите это на trycf.com

Так что ты можешь сделать

Если у вас есть несколько ядер ЦП, и если вы решите, что синтаксический анализ файла Excel является медленным процессом, вы можете прочитать файл в одном потоке, но затем разбить его на несколько частей и проанализировать каждое из них в нескольких потоки.

Это может быть или не быть более эффективным, так как многопоточность увеличивает накладные расходы, и вам придется разделить данные, а затем собрать их вместе, в конце концов, так что YMMV - вам нужно провести некоторое тестирование для этого.

Смотрите также

Я рекомендую прочитать соответствующие сообщения в блоге, которые я опубликовал на Rasia.io:

Легкий Параллелизм в Люси

Безопасный параллелизм с Люси

Использование Java для эффективного чтения части большого файла

Другие вопросы по тегам