Domanda

Ho una directory piena (~ 10 3 , 10 4 ) di file XML da cui ho bisogno di estrarre il contenuto di diversi campi. Ho testato diversi parser xml e poiché non ho bisogno di convalidare il contenuto (costoso) stavo pensando di usare semplicemente xml.parsers.expat (il più veloce) per passare attraverso i file, uno per uno per estrarre il dati.

  1. C'è un modo più efficiente? (la semplice corrispondenza del testo non funziona)
  2. Devo emettere un nuovo ParserCreate () per ogni nuovo file (o stringa) o posso riutilizzare lo stesso per ogni file?
  3. Qualche avvertimento?

Grazie!

È stato utile?

Soluzione

Il modo più veloce sarebbe quello di abbinare le stringhe (con, ad esempio, le espressioni regolari) invece di analizzare XML - a seconda dei tuoi XML questo potrebbe effettivamente funzionare.

Ma la cosa più importante è questa: invece di pensare a diverse opzioni, implementale e cronometra su un piccolo set. Ciò richiederà all'incirca la stessa quantità di tempo e ti darà numeri reali che ti faranno avanzare.

EDIT:

  • I file si trovano su un'unità locale o un'unità di rete? L'I / O di rete ti ucciderà qui.
  • Il problema si parallelizza in modo banale: puoi dividere il lavoro tra più computer (o più processi su un computer multicore).

Altri suggerimenti

Di solito, suggerirei di usare iterparse di ElementTree o, per maggiore velocità, la sua controparte di lxml . Prova anche a utilizzare Processing (integrato con 2.6) per parallelizzare.

La cosa importante di iterparse è che ottieni le (sotto-) strutture degli elementi mentre vengono analizzate.

import xml.etree.cElementTree as ET
xml_it = ET.iterparse("some.xml")
event, elem = xml_it.next()

evento sarà sempre la stringa " end " in questo caso, ma puoi anche inizializzare il parser per parlarti anche di nuovi elementi mentre vengono analizzati. Non hai alcuna garanzia che tutti gli elementi figlio saranno stati analizzati a quel punto, ma gli attributi sono lì, se ti interessa solo quello.

Un altro punto è che puoi interrompere la lettura anticipata degli elementi dall'iteratore, ovvero prima che l'intero documento sia stato elaborato.

Se i file sono grandi (sono?), esiste un linguaggio comune per mantenere costante l'utilizzo della memoria come in un parser di streaming.

Se sai che i file XML sono generati usando lo stesso algoritmo, potrebbe essere più efficiente non eseguire alcun analisi XML. Per esempio. se sai che i dati sono nelle righe 3, 4 e 5, potresti leggere il file riga per riga e quindi utilizzare espressioni regolari.

Ovviamente, questo approccio fallirebbe se i file non fossero generati dalla macchina o originati da generatori diversi o se il generatore dovesse cambiare nel tempo. Tuttavia, sono ottimista sul fatto che sarebbe più efficiente.

Il fatto di riciclare o meno gli oggetti parser è in gran parte irrilevante. Verranno creati molti più oggetti, quindi un singolo oggetto parser non conta molto.

Una cosa che non hai indicato è se stai leggendo l'XML in un DOM di qualche tipo. Immagino che probabilmente non lo sei, ma per caso lo sei, non farlo. Utilizzare invece xml.sax. L'utilizzo di SAX anziché DOM ti consentirà di ottenere un notevole aumento delle prestazioni.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top