2017-03-21 7 views
0

Alamofireを使用してWebサーバーから5つのXMLファイルをダウンロードし、SWXMLHashを使用して解析しています。最後のファイルは、最初の4つのファイルに依存し、最初の4つのファイルには、そのエントリのうちのいくつかが最初の4つに含まれるエントリを参照する方法で決まります。最後のファイルのダウンロードが開始される前に、4つのファイルがすべてダウンロードされるように、ダウンロードコードにカスケードスタイルの構造を使用します。複数のXMLファイルをダウンロードして解析する効率を改善する

let destination: DownloadRequest.DownloadFileDestination = { _, _ in 
     let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, 
                   .userDomainMask, true)[0] 
     let documentsURL = URL(fileURLWithPath: documentsPath, isDirectory: true) 
     let fileURL = documentsURL.appendingPathComponent("image.png") 

     return (fileURL, [.removePreviousFile, .createIntermediateDirectories]) 
    } 



    // Download Category files 
    Alamofire.download(self.ottawaOpenDataCategoriesURL, to: 
     destination) 
     .downloadProgress { progress in 
      //print("Download Progress for Category: \(progress.fractionCompleted)") 
      if let pv = self.progressViewController { 
       pv.updateProgress(progress.fractionCompleted * 100.0) //Alamofire returns 1 for complete process 
      } 
     } 

     .responseData { response in 
      // Check 304 response to see if new file is available 
      if response.response?.statusCode == self.HTTP_STATUS_FILE_NOT_CHANGE { 
       return 
      } 

      if let data = response.result.value { 
       let xml = self.initXMLParser(data: data) 
       self.storeCategoryXMLStream(xml) 
      } 


      // After complete downloading or get error, try download Options 
      Alamofire.download(self.ottawaOpenDataOptionsURL, to: 
       destination) 
       .downloadProgress { progress in 
        if let pv = self.progressViewController { 
         pv.updateProgress(progress.fractionCompleted * 100.0) //Alamofire returns 1 for complete process 
        } 
       } 

       .responseData { response in 
        // Check 304 response to see if new file is available 
        if response.response?.statusCode == self.HTTP_STATUS_FILE_NOT_CHANGE { 
         return 
        } 

        if let data = response.result.value { 
         let xml = self.initXMLParser(data: data) 
         self.storeEventOptionsXMLStream(xml) 
        } 

        // After complete downloading or get error, try download Locations 
        Alamofire.download(self.ottawaOpenDataLocationsURL, to: 
         destination) 
         .downloadProgress { progress in 
          if let pv = self.progressViewController { 
           pv.updateProgress(progress.fractionCompleted * 100.0) //Alamofire returns 1 for complete process 
          } 
         } 

         .responseData { response in 
          // Check 304 response to see if new file is available 
          if response.response?.statusCode == self.HTTP_STATUS_FILE_NOT_CHANGE { 
           return 
          } 

          if let data = response.result.value { 
           let xml = self.initXMLParser(data: data) 
           self.storeVenuesXMLStream(xml) 
          } 

          // After complete downloading or get error, try download CitrSectors 
          Alamofire.download(self.ottawaOpenDataCitySectorsURL, to: 
           destination) 
           .downloadProgress { progress in 
            if let pv = self.progressViewController { 
             pv.updateProgress(progress.fractionCompleted * 100.0) //Alamofire returns 1 for complete process 
            } 
           } 

           .responseData { response in 
            // Check 304 response to see if new file is available 
            if response.response?.statusCode == self.HTTP_STATUS_FILE_NOT_CHANGE { 
             return 
            } 

            if let data = response.result.value { 
             let xml = self.initXMLParser(data: data) 
             self.storeCitySectorsXMLStream(xml) 
            } 


            // After complete downloading or get error, try download events 
            Alamofire.download(self.ottawaOpenDataEventsURL, to: 
             destination) 
             .downloadProgress { progress in 
              if let pv = self.progressViewController { 
               pv.updateProgress(progress.fractionCompleted * 100.0) //Alamofire returns 1 for complete process 
              } 
             } 

             .responseData { response in 
              // Check 304 response to see if new file is available 
              if response.response?.statusCode == self.HTTP_STATUS_FILE_NOT_CHANGE { 
               return 
              } 

              if let data = response.result.value { 
               let xml = self.initXMLParser(data: data) 
               self.storeEventsXMLStream(xml) 
              } 

             } 
           } 
         } 
       } 

     } 

ご覧のとおり、各ダウンロードセグメントは、前のセグメントが完了するのを待ちます。また、プログレスバーはダウンロードプロセス中に更新されます。ほとんどのXMLファイルは、小さいものから適切なサイズ(80行 - 10K行)まであり、最後のものは最大で約200K行が含まれています。

カスケードスタイルの構造であるかどうかはわかりませんが、最初の4つのファイルをダウンロードして解析するのに約10秒かかります。速くすることは可能ですか?私は効率を改善できるかどうかを知りたいだけです。ここでは、CPU使用量とメモリ使用量のスクリーンショットです。

enter image description here

P.S私はシミュレータ上でこのアプリを実行していますよ。

答えて

1

最初の4ダウンロードは相互依存関係ではないので、それらを同時にダウンロードすることができます。ディスパッチグループを使用して、5回目のダウンロードの実行を同期させます。要するに

、全体の動作は次のようになります。

let group = DispatchGroup() 

group.enter() 
Alamofire.download(first url).responseData { 
    process first url 
    group.leave() 
} 

group.enter() 
Alamofire.download(second url).responseData { 
    process second url 
    group.leave() 
} 

repeat for third and fourth url 

group.notify(queue:Dispatch.main) { 
    Alamofire.download(fifth url).responseData { 
     process 5th url 
    } 
} 
+0

ありがとう!それはかなり大幅に改善されます(約4秒まで)。しかし、私はgroup.notifyの使用法を "group.notify(queue:.main)"に修正しなければなりませんでした。あなたはそれを参照のために修正できますか?私はそれを正しいものとしてマークします。再度、感謝します。 – user30646

+0

大きなファイルを解析するために追加するもう1つの点 - SWXMLHashは遅延解析を行うことができるので、ファイルや特定の部分からすべてを読み込んでいる場合は、遅延読み込みによってパフォーマンスが大幅に向上します。 https://github.com/drmohundro/SWXMLHash#configurationを参照してください。 –

関連する問題