복붙노트

[SCALA] 스칼라에서 병렬 파일 처리

SCALA

스칼라에서 병렬 파일 처리

내가 병렬로 지정된 폴더에있는 파일을 처리 할 필요가 가정하자. 자바에서 나는 폴더와 FileProcessor 스레드 풀에서 파일 이름을 읽어 FolderReader 스레드를 만들 것입니다. FolderReader 파일명을 판독하고, 풀 실행기 파일 처리 기능 (의 Runnable)을 제출한다.

스칼라에서 나는 두 가지 옵션을 참조하십시오

그것은 의미가 있습니까? 최선의 선택은 무엇인가?

해결법

  1. ==============================

    1.나는 가능한 멀리 할 수있는 스레드에서 계속 내 모든 에너지와 함께 제안한다. 다행히 우리는 아래에 무슨 일이 일어나고 있는지 알아서 더 추상화를 가지고 있고, 귀하의 경우는 (당신이 할 수있는 동안) 당신이 사용 배우 할 필요가 없습니다 나에게 나타납니다하지만 당신은 선물이라는 간단한 추상화를 사용할 수 있습니다. 그들은 Akka 오픈 소스 라이브러리의 일부, 나는 스칼라 표준 라이브러리의 일부가 될 미래의 생각뿐만 아니라.

    나는 가능한 멀리 할 수있는 스레드에서 계속 내 모든 에너지와 함께 제안한다. 다행히 우리는 아래에 무슨 일이 일어나고 있는지 알아서 더 추상화를 가지고 있고, 귀하의 경우는 (당신이 할 수있는 동안) 당신이 사용 배우 할 필요가 없습니다 나에게 나타납니다하지만 당신은 선물이라는 간단한 추상화를 사용할 수 있습니다. 그들은 Akka 오픈 소스 라이브러리의 일부, 나는 스칼라 표준 라이브러리의 일부가 될 미래의 생각뿐만 아니라.

    미래 [T]는 단순히 미래에 T를 반환합니다 무언가이다.

    당신이 미래를 실행하는 데 필요한 모든, 당신은 자바 실행 프로그램 서비스에서 파생 할 수있는 암시의 ExecutionContext를하는 것입니다. 그런 다음, 우아한 API와 미래가 미래의 컬렉션으로 컬렉션을 변환 할 수있는 모나드라는 사실을 즐길 수있는 결과 등을 수집합니다. 난 당신이 http://doc.akka.io/docs/akka/2.0.1/scala/futures.html에 모양을 제공하는 것이 좋습니다

    object TestingFutures {
      implicit val executorService = Executors.newFixedThreadPool(20)
      implicit val executorContext = ExecutionContext.fromExecutorService(executorService)
    
      def testFutures(myList:List[String]):List[String]= {
    
        val listOfFutures : Future[List[String]] = Future.traverse(myList){
          aString => Future{
                            aString.reverse
                           }
         }
        val result:List[String] = Await.result(listOfFutures,1 minute)
        result
    
      }
    }
    

    여기서 살펴 봐야 할 것들이 많다 :

    Akka 선물 보는 다른 많은 이유가있다.

  2. ==============================

    2.당신이 무슨 일을하는지에 따라, 단순하게 할 수있다

    당신이 무슨 일을하는지에 따라, 단순하게 할 수있다

    for(file<-files.par){
       //process the file
    }
    
  3. ==============================

    3.이상적으로 두 배우를 사용해야합니다. 파일 목록을 읽기위한 하나, 실제로 파일을 읽기위한 하나.

    이상적으로 두 배우를 사용해야합니다. 파일 목록을 읽기위한 하나, 실제로 파일을 읽기위한 하나.

    당신은 단순히 첫 번째 배우로 하나의 "시작"메시지를 전송하여 프로세스를 시작합니다. 배우는 파일 목록을 읽고, 두 번째 배우로 메시지를 보낼 수 있습니다. 두 번째 배우가 다음 파일을 읽고 내용을 처리합니다.

    복잡하게 보일 수도 여러 배우, 데, 실제로 당신이 이론적 OO 시스템처럼, 서로 통신 개체의 무리가 있다는 점에서 좋은 일이다.

    편집 : 당신은 정말 하나의 파일의 동시 읽기를하고 일을해서는 안된다.

  4. ==============================

    4.나는 그가 나를 이길 제외 Edmondo1984 @했던 정확하게 쓸 거라고. 큰 방법 : 나는 두 번째 그의 제안. 나는 또한 당신이 Akka 2.0.2에 대한 문서를 읽어 볼 것을 제안합니다. 뿐만 아니라, 나는 당신에게 조금 더 구체적인 예를주지 :

    나는 그가 나를 이길 제외 Edmondo1984 @했던 정확하게 쓸 거라고. 큰 방법 : 나는 두 번째 그의 제안. 나는 또한 당신이 Akka 2.0.2에 대한 문서를 읽어 볼 것을 제안합니다. 뿐만 아니라, 나는 당신에게 조금 더 구체적인 예를주지 :

    import akka.dispatch.{ExecutionContext, Future, Await}
    import akka.util.duration._
    import java.util.concurrent.Executors
    import java.io.File
    
    val execService = Executors.newCachedThreadPool()
    implicit val execContext = ExecutionContext.fromExecutorService(execService)
    
    val tmp = new File("/tmp/")
    val files = tmp.listFiles()
    val workers = files.map { f =>
      Future {
        f.getAbsolutePath()
      }
    }.toSeq
    val result = Future.sequence(workers)
    result.onSuccess {
      case filenames =>
        filenames.foreach { fn =>
          println(fn)
        }
    }
    
    // Artificial just to make things work for the example
    Thread.sleep(100)
    execContext.shutdown()
    

    여기에 내가 대신 트래버스의 순서를 사용하지만, 차이는 사용자의 요구에 따라 예정이다.

    미래, 내 친구와 함께 이동; 액터는이 경우에 더 고통스러운 방법입니다.

  5. ==============================

    5.그러나 사용 배우 경우, 그 문제점은 무엇입니까?

    그러나 사용 배우 경우, 그 문제점은 무엇입니까?

    우리는 몇 가지 특성 파일에 읽기 / 쓰기해야합니다. 내 자바 예제가있다. 하지만 여전히 Akka 배우와.

    않을까의 우리가 배우가 ActorFile 하나 개의 파일을 나타내는 말. 흠 .. 아마 그것은 하나 개의 파일을 나타낼 수 없습니다. 권리? (이 수 좋을 것이다). 그럼 그 다음 PropertyFilesActor 같은 여러 파일을 나타냅니다 :

    왜 이런 일을 사용하지 것이다 :

    public class PropertyFilesActor extends UntypedActor {
    
        Map<String, String> filesContent = new LinkedHashMap<String, String>();
    
        { // here we should use real files of cource
            filesContent.put("file1.xml", "");
            filesContent.put("file2.xml", "");
        }
    
        @Override
        public void onReceive(Object message) throws Exception {
    
            if (message instanceof WriteMessage)  {
                WriteMessage writeMessage = (WriteMessage) message;
                String content = filesContent.get(writeMessage.fileName);
                String newContent = content + writeMessage.stringToWrite;
                filesContent.put(writeMessage.fileName, newContent);
            }
    
            else if (message instanceof ReadMessage) {
                ReadMessage readMessage = (ReadMessage) message;
                String currentContent = filesContent.get(readMessage.fileName);
                // Send the current content back to the sender
                getSender().tell(new ReadMessage(readMessage.fileName, currentContent), getSelf());
            }
    
            else unhandled(message);
    
        }
    
    }
    

    ... 매개 변수와 함께 갈 것입니다 메시지 (파일 이름)

    이 같은 메시지를 받아들이고, 자신의-상자가 있습니다 :

    그 메시지는 순서대로 인 박스에로 antoher 하나씩 저장됩니다. 저장 / 읽기, 그 사이에 의견을 보낸 사람을 보내는 - 배우 박스에서 메시지를 수신하여 작업을 할 것입니다! 메시지 다시.

    우리는 속성 파일에 기록하고, 웹 페이지의 내용을 보여주는 보내는 경우 따라서,하자들은 말한다. 우리는 즉시 우리가 (아약스) 단지 업데이트 된 파일에서 데이터 페이지의 업데이트 부분을 피드백을 수신 한과 (우리가 파일에 데이터를 저장하는 메시지를 보낸 직후) 페이지를 보여주는 시작할 수 있습니다.

  6. ==============================

    6.음, 파일을 잡고 병렬 구조를 스틱

    음, 파일을 잡고 병렬 구조를 스틱

    scala> new java.io.File("/tmp").listFiles.par
    res0: scala.collection.parallel.mutable.ParArray[java.io.File] = ParArray( ... )
    

    그때...

    scala> res0 map (_.length)
    res1: scala.collection.parallel.mutable.ParArray[Long] = ParArray(4943, 1960, 4208, 103266, 363 ... )
    
  7. from https://stackoverflow.com/questions/11576439/parallel-file-processing-in-scala by cc-by-sa and MIT license