PC SOFT

GRUPOS DE DISCUSSÃO PROFISSIONAL
WINDEVWEBDEV e WINDEV Mobile

Inicio → WINDEV 25 → Aqui apresento 3 tipos de leituras de arquivos CSV com velocidades diferentes de leitura e processamento.
Aqui apresento 3 tipos de leituras de arquivos CSV com velocidades diferentes de leitura e processamento.
Iniciado por Boller, jan., 10 2023 5:07 PM - Sem resposta
Membro registado
3.660 mensagems
Popularité : +175 (223 votes)
Publicado em janeiro, 10 2023 - 5:07 PM
Prezados,

Levando em conta um arquivo de 5gb de csv,
TESTES FORAM USANDO UM SSD SANSUNG
BrowserRunApp("https://files.data.gouv.fr/insee-sirene/StockEtablissement_utf8.zip")

Temos:

LEITURA SIMPLES - NORMALMENTE É BEM LENTA (15 min) +-

// Vérifie si le fichier de test à bien été renseigné
IF fFileExist(SAI_CheminFichier) = False THEN
Error("Le fichier de test doit être renseigné.")
ReturnToCapture(SAI_CheminFichier)
END


//Parcours classique d'un fichier de données d'un volume "correct"

FIL_Code1.Color = LightBlue
FIL_Code1.ZOrder = 100

//Ouverture du fichier texte
IDFichier is int
IDFichier = fOpen(SAI_CheminFichier, foRead)


sLigneLue is string
nNbreLignesLues is int
nTailleTraitée is 8-byte int

JAUGE_SansNom2.MaxValue = fSize(SAI_CheminFichier)

//Donnera le temps de lecture du fichier
MonChrono is Chrono
MonChrono.Start()

IF IDFichier = -1 THEN
// Affichage du message d'erreur si l'ouverture n'a pas été effectuée
Error(ErrorInfo(errMessage))
RETURN
END


//Boucle de lecture du fichier
LOOP

// Lecture de la première ligne du fichier
sLigneLue = fReadLine(IDFichier,Charact(10))

// Fin de fichier ?
IF sLigneLue = EOT THEN BREAK

//Mise à jour de la jauge pour suivre l'avancement
nTailleTraitée += Length(sLigneLue)
JAUGE_SansNom2 = nTailleTraitée

nNbreLignesLues ++

let reste = modulo(nNbreLignesLues, 5000)
IF reste = 0 THEN
d is Duration = MonChrono.Value
LIB_Chrono = DurationToString(d, "MMm SSs CCCms")
END

END


MonChrono.End()

d is Duration = MonChrono.Value

NOTE_AffichageRésultats += [CR] + "************" + CR + "Lecture classique : " + DurationToString(d, "MMm SSs CCCms") + CR + "Nombre de lignes lues : " + NumToString(nNbreLignesLues, "dS")

FIL_Code1.Color = Black

// Fermeture du fichier
fClose(IDFichier)

CASE ERROR:
Error(ErrorInfo())


LEITURA EM BLOCOS DE LEITURA E GRAVAÇÃO (42 segundos) +- RECOMENDAVEL A SUA UTILIZAÇÃO
DESEMPENHO AUMENTA COM A CAPACIDADE DE PROCESSAMENTO E SSD/NVM2 ONDE FOR EXECUTADO

// Vérifie si le fichier de test à bien été renseigné
IF fFileExist(SAI_CheminFichier) = False THEN
Error("Le fichier de test doit être renseigné.")
ReturnToCapture(SAI_CheminFichier)
END

FIL_Code2.Color = LightBlue
FIL_Code2.ZOrder = 100


IDFichier is int
IDFichier = fOpen(SAI_CheminFichier, foRead)


sUnLotDeLignes is string
sSéparateurLigne is string ANSI = Charact(10)
nNbreLignesLues is int

nPositionFinDernièreLigneComplète is int

nTailleTraitée is 8-byte int
nTailleATraiter is 8-byte int = fSize(SAI_CheminFichier)
//Lecture par bloc : on définit la taille du bloc
nTailleBloc is int = 500000
sResteBlocPrécédent is string

JAUGE_SansNom2.MaxValue = nTailleATraiter


//Donnera le temps de lecture du fichier
MonChrono is Chrono
MonChrono.Start()


IF IDFichier = -1 THEN
// Affichage du message d'erreur si l'ouverture n'a pas été effectuée
Error(ErrorInfo(errMessage))
RETURN
END


LOOP

//Lecture par bloc
sUnLotDeLignes = fRead(IDFichier,nTailleBloc)
sUnLotDeLignes = sResteBlocPrécédent + sUnLotDeLignes

//La dernière ligne du bloc n'est probablement pas complète, donc il faut le gérer
nPositionFinDernièreLigneComplète = Position(sUnLotDeLignes, sSéparateurLigne, 0, FromEnd)

sResteBlocPrécédent = sUnLotDeLignes[[nPositionFinDernièreLigneComplète+Length(sSéparateurLigne) TO]]

sUnLotDeLignes = sUnLotDeLignes[[1 TO nPositionFinDernièreLigneComplète-Length(sSéparateurLigne)]]

//Si le bloc est vide, on sort
IF sUnLotDeLignes = "" THEN
BREAK
END

FOR EACH STRING sLigneLue OF sUnLotDeLignes SÉPARÉE BY sSéparateurLigne

nNbreLignesLues++

END

//Mise à jour de la jauge pour suivre l'avancement
nTailleTraitée += Length(sUnLotDeLignes)
JAUGE_SansNom2 = nTailleTraitée
d is Duration = MonChrono.Value
LIB_Chrono = DurationToString(d, "MMm SSs CCCms")

END

MonChrono.End()
d is Duration = MonChrono.Value

NOTE_AffichageRésultats += [CR] + "************" + CR + "Lecture par bloc : "+ CR + DurationToString(d, "MMm SSs CCCms")+ CR + "Nombre de lignes lues : "+ NumToString(nNbreLignesLues, "dS")

FIL_Code2.Color = Black

// Fermeture du fichier
fClose(IDFichier)


LEITURA EM BLOCOS DE LEITURA E GRAVAÇÃO (30 segundos) +-

// Vérifie si le fichier de test à bien été renseigné
IF fFileExist(SAI_CheminFichier) = False THEN
Error("Le fichier de test doit être renseigné.")
ReturnToCapture(SAI_CheminFichier)
END

FIL_Code3.Color = LightBlue
FIL_Code3.ZOrder = 100


IDFichier is int
sUnLotDeLignes is string
sSéparateurLigne is string ANSI = Charact(10)

IDFichier = fOpen(SAI_CheminFichier,foRead)

nPositionFinDernièreLigneComplète is int

nTailleTraitée is 8-byte int
nTailleATraiter is 8-byte int = fSize(SAI_CheminFichier)
nTailleBloc is int = 500000
sResteBlocPrécédent is string

tabTaches is array of ParallelTask
UneTache is Description of ParallelTask

JAUGE_SansNom2.MaxValue = nTailleATraiter

//Démarre le chrono
MonChrono is Chrono
MonChrono.Start()

IF IDFichier = -1 THEN
// Affichage du message d'erreur si l'ouverture n'a pas été effectuée
Error(ErrorInfo(errMessage))
RETURN
END

LOOP

//Lecture par bloc
sUnLotDeLignes = fRead(IDFichier,nTailleBloc)
sUnLotDeLignes = sResteBlocPrécédent + sUnLotDeLignes

//La dernière ligne du bloc n'est probablement pas complète, donc il faut le gérer
nPositionFinDernièreLigneComplète = Position(sUnLotDeLignes, sSéparateurLigne, 0, FromEnd)
sResteBlocPrécédent = sUnLotDeLignes[[nPositionFinDernièreLigneComplète+Length(sSéparateurLigne) TO]]
sUnLotDeLignes = sUnLotDeLignes[[1 TO nPositionFinDernièreLigneComplète-Length(sSéparateurLigne)]]

IF sUnLotDeLignes = "" THEN
BREAK
END

//On traite chaque bloc dans des tâches parallèles pour encore optimiser les performances
UneTache.Procedure = pTraiteBloc
UneTache.Parameter[1] = sUnLotDeLignes
UneTache.Parameter[2] = sSéparateurLigne
Add(tabTaches, ParallelTaskExecute(UneTache))

//Mise à jour de la jauge pour suivre l'avancement
nTailleTraitée += Length(sUnLotDeLignes)
JAUGE_SansNom2 = nTailleTraitée

d is Duration = MonChrono.Value
LIB_Chrono = DurationToString(d, "MMm SSs CCCms")

END

ParallelTaskExecuteAfterAll(tabTaches, pFIN, (), ptoMainThread)

// Fermeture du fichier
fClose(IDFichier)


INTERNAL PROCEDURE pTraiteBloc (LOCAL s_Bloc is string, LOCAL s_SéparateurLigne is string)

//Traite chaque ligne du bloc passé en paramètre
sLigneLueDansBloc is string
nNbLigneBloc is int

FOR EACH STRING sLigneLueDansBloc OF s_Bloc SÉPARÉE BY s_SéparateurLigne
nNbLigneBloc++
END


RETURN nNbLigneBloc
END

INTERNAL PROCEDURE pFIN()

nTotalLigne is int
nTotalLigneUneTache is int

xx is ParallelTask

FOR EACH xx OF tabTaches

nTotalLigneUneTache = xx.ReturnedValue
nTotalLigne += nTotalLigneUneTache

END

MonChrono.End()
d is Duration = MonChrono.Value

NOTE_AffichageRésultats += [CR] + "************" + CR + "Lecture par bloc et TâcheParallèle : "+ CR + DurationToString(d, "MMm SSs CCCms")+ CR + "Nombre de lignes lues : "+ NumToString(nTotalLigne, "dS")
NOTE_AffichageRésultats += [CR] + "Nombre de tâches parallèles exécutées : "+ NumToString(tabTaches.Count, "dS")

FIL_Code3.Color = Black

END


--
Adriano José Boller
______________________________________________
Consultor e Representante Oficial da
PcSoft no Brasil
+55 (41) 99949 1800
adrianoboller@gmail.com
skype: adrianoboller
http://wxinformatica.com.br/