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

Я пытаюсь прочитать большой файл 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 Ответ

0 голосов
/ 16 мая 2018

Многопоточность - это не решение всех проблем

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

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

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

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

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

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

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

Если вы хотите иметь доступ к ней после завершения потока, вам необходимо установитьэто в НИТЕ Сфера.Рассмотрим следующий пример:

<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:

Легкий параллелизм в Lucee

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

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

...