Piètres performances en exécution macro Calc de LibreOffice

Bonjour à tous,

En ouvrant ma messagerie ce matin, je suis tombé sur l'issue suivant :

https://bugs.freedesktop.org/show_bug.cgi?id=45607

et j'ai pu constater moi-même les piètres performances de l'exécution de
cette macro avec LibreOffice, quelque soit la version utilisée...la future
3.5, en outre, est une catastrophe, 3.5 fois plus lente que les versions
précédentes de LibO. Comme quoi, ma décision de continuer à garder OOo
3.2.1 se justifie de plus en plus...

Alex

Bonjour à tous,

En ouvrant ma messagerie ce matin, je suis tombé sur l'issue suivant :

https://bugs.freedesktop.org/show_bug.cgi?id=45607

et j'ai pu constater moi-même les piètres performances de l'exécution de
cette macro avec LibreOffice, quelque soit la version utilisée...la future
3.5, en outre, est une catastrophe, 3.5 fois plus lente que les versions
précédentes de LibO. Comme quoi, ma décision de continuer à garder OOo
3.2.1 se justifie de plus en plus...

Alex

Bonjour,
Avec ma configuration LibO 3.5 RC2, la macro s'exécute en un peu plus de 38 sec
Le code est peut-être à revoir.
J.M

Raahhhhhhh !!!
Avec mon turbo : 0.577 s
Ce qui est bizarre est le temps qui change (peu) sur plusieurs tests (de 0.577 s à
0.609 s).
LibO 3.5 RC2 - Win7 64b

Bon surf,
Christian

Bon, le PB est dans la fonction (Function show...)
si je l'ignore, c'est bien 0.577 s, sinon, cata : 43.633 s

Bon surf
Christian

Avec ma configuration LibO 3.5 RC2, la macro s'exécute en un peu plus de 38 sec
Le code est peut-être à revoir.
J.M

Raahhhhhhh !!!
Avec mon turbo : 0.577 s

Bon, le PB est dans la fonction (Function show...)
si je l'ignore, c'est bien 0.577 s, sinon, cata : 43.633 s

Bon surf
Christian

Et moi, je tombe alors à 2 sec

autres tests

la ligne oCell.String = "abc"
est responsable de la moitié du temps mesuré
sans elle, l'exécution descend à 4,354s
la ligne oCell.setFormula(fun)
absorbe la quasi totalité du temps mesuré
sans elle, l'exécution descend à 0,39s

Par curiosité, j'ai inséré la formule sans le signe "=",
le temps d'exécution descend à 0,519s

Puis-je en déduire que Calc recalculant la formule à chaque insertion par la macro, c'est ce qui ralentit le tout ?

Suspendre le recalcul en début de macro et le réactiver à la fin apporterait un gain, mais est-ce bien là que réside le problème ?
Je ne sais pas -encore- faire ceci, mais ça viendra…

C_Lucien

Bonsoir,

De : lutch [mailto:lutch@free.fr]
Envoyé : samedi 4 février 2012 18:52

[...]

Par curiosité, j'ai inséré la formule sans le signe "=",
le temps d'exécution descend à 0,519s

Puis-je en déduire que Calc recalculant la formule à chaque insertion
par la macro, c'est ce qui ralentit le tout ?

Suspendre le recalcul en début de macro et le réactiver à la fin
apporterait un gain, mais est-ce bien là que réside le problème ?
Je ne sais pas -encore- faire ceci, mais ça viendra…

C_Lucien

Je l'ai déjà utilisé et ça m'a fait gagner beaucoup de temps dans une macro
travaillant sur un classeur avec un très grand nombre de calculs.

Pour inhiber le recalcul automatique:
Nom_du_Classeur.enableAutomaticCalculation(False)

Pour autoriser le recalcul automatique après avoir tout recalculé
Nom_du_Classeur.CalculateAll
Nom_du_Classeur.enableAutomaticCalculation(True)

Ceci à condition de ne pas avoir besoin de valeurs calculées entre temps ...

Bonne soirée,

Michel

Testé sur deux configurations :

  * Config 1 : LibO 3.4.4 (build Ubuntu), Ubuntu 11.10 64 bits, Xeon
    3000, 8Go RAM : 17.855"
  * Config 2 : LibO 3.4.5 (standard), XP SP3, AMD Athlon 3200+, 2 Go RAM
    : 37.751"

Si on désactive le recalcul automatique, les temps d'exécution tombent respectivement à 0.931" et 1.875". Le recalcul lui-même par F9 est très rapide, bien plus que lors de l'insertion des formules par la macro.

Mon hypothèse : lors de l'insertion de la formule dans chaque cellule, toutes les cellules sont recalculées à chaque insertion, alors qu'en déactivant le recalcul automatique et en l'exécutant par F9, chaque cellule n'est calculée qu'une seule fois, ou le recalcul est optimisé d'une manière quelconque.

On peut voir en effet qu'au fur et à mesure que la feuille se remplit (en mode recalcul activé), la progression vers le bas se ralentit.

Donc, a priori, ça ne me paraît pas anormal en ce qui concerne le comportement. Savoir ensuite si le temps d'exécution lui-même est anormal ou pas, je ne sais pas. Il faudrait comparer avec des versions antérieures de LibO ou d'OOo sur la même configuration pour avoir quelque chose de comparable.

Cordialement ;
Marc Romano

Bonsoir,

De : lutch [mailto:lutch@free.fr]
Envoyé : samedi 4 février 2012 18:52

[...]

Par curiosité, j'ai inséré la formule sans le signe "=",
le temps d'exécution descend à 0,519s

Puis-je en déduire que Calc recalculant la formule à chaque insertion
par la macro, c'est ce qui ralentit le tout ?

Suspendre le recalcul en début de macro et le réactiver à la fin
apporterait un gain, mais est-ce bien là que réside le problème ?
Je ne sais pas -encore- faire ceci, mais ça viendra…

C_Lucien

Je l'ai déjà utilisé et ça m'a fait gagner beaucoup de temps dans une macro
travaillant sur un classeur avec un très grand nombre de calculs.

Pour inhiber le recalcul automatique:
Nom_du_Classeur.enableAutomaticCalculation(False)

Pour autoriser le recalcul automatique après avoir tout recalculé
Nom_du_Classeur.CalculateAll
Nom_du_Classeur.enableAutomaticCalculation(True)

Ceci à condition de ne pas avoir besoin de valeurs calculées entre temps ...

Bonne soirée,

Michel

en effet ! Merci.
Temps d'exécution 0,506s

À toutes fins utiles, voici la macro modifiée

Function show_number(ByVal nr As Integer,ByVal empty As Boolean) As String
show_number = ""
If Not empty Then
show_number = Trim(Str(nr))+ "."
End If
End Function
'********************
Sub test
Const END_ROW As Integer = 199

Dim document As Object
Dim dispatcher As Object

document = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")

Dim oDoc As Object
Dim oSheet As Object
Dim oRange As Object
Dim oCell As Object

oDoc = ThisComponent
oSheet = oDoc.getCurrentController.ActiveSheet
oDoc.enableAutomaticCalculation(False)

' Select and clean the test cell range

oRange = oSheet.getCellRangeByPosition(0, 0, 1, END_ROW)
oDoc.CurrentController.select(oRange)

dispatcher.executeDispatch(document, ".uno:ClearContents", "", 0, Array())

Dim fun As String

fun = "=show_number(ROW(); isblank(indirect(""B"" & ROW())))"

Dim start_time As Long

start_time = GetSystemTicks()

' Fill the test cell range:
' column 1: formula for displaying the row number
' column 2: a constant string

Dim row As Integer

For row = 0 To END_ROW
oRange = oSheet.getCellRangeByPosition(0, row, 0, row)
oDoc.CurrentController.select(oRange)
oCell = oSheet.getCellByPosition(0, row)
oCell.setFormula(fun)
oCell = oSheet.getCellByPosition(1, row)
oCell.String = "abc"
Next row

oRange = oSheet.getCellRangeByPosition(0, 0, 0, 0)
oDoc.CurrentController.select(oRange)

oRange = oDoc.createInstance("com.sun.star.sheet.SheetCellRanges")
oDoc.CurrentController.select(oRange)

Print "Test executed in " + (GetSystemTicks() - start_time)/1000 + " s"
oDoc.enableAutomaticCalculation(true)
End Sub

J'ai appris quelque chose ce soir…
C_Lucien

Bonjour

J'ai commenté l'Issue avec quelques autres propositions d'amélioration...

Cordialement
Pierre-Yves

Bonjour

J'ai commenté l'Issue avec quelques autres propositions d'amélioration...

Cordialement
Pierre-Yves

--
View this message in context: http://nabble.documentfoundation.org/Pietres-performances-en-execution-macro-Calc-de-LibreOffice-tp3715374p3716810.html
Sent from the Users mailing list archive at Nabble.com.

Bonjour,

merci, c'est limpide, j'ai tout compris.

Une question en marge, mon ignorance est définitivement immense.
Conscient que je déborde quelque peu du sujet initial, je rendrai compte de mes prochaines interrogations sur un autre fil si besoin.

Les 2 lignes

thisComponent.enableAutomaticCalculation(true)
thisComponent.calculateAll

ne font pas la même chose n'est-ce pas ?

Si je neutralise la 2ème, le temps d'exécution pour *1999 lignes* tombe de 2,624s à 0,657s
Je suppose qu'en réactivant seulement le calcul automatique, les valeurs ne se recalculeront qu'au moment où on modifiera une cellule quelconque de la feuille.
Alors qu'en forçant le recalcul, on obtient de facto toutes les nouvelles valeurs.
Je suppose qu'en présence de classeurs complexes, dont les feuilles sont interdépendantes, ce choix ne sera pas anodin.
Le choix de l'une ou l'autre option dépend de l'architecture de la feuille, voire de tout le classeur.

Bonne journée à toutes et à tous
C_Lucien

lutch wrote

Les 2 lignes

thisComponent.enableAutomaticCalculation(true)
thisComponent.calculateAll

ne font pas la même chose n'est-ce pas ?

Non en effet... La première détermine si le recalcul est automatique ou non,
la seconde provoque le recalcul.

On pourrait ajouter :
thisComponent.calculate 'mise à jour des formules modifiées

lutch wrote

Le choix de l'une ou l'autre option dépend de l'architecture de la
feuille, voire de tout le classeur.

Ici nous sommes dans un cas particulier de "saisie en masse" pendant
laquelle l'utilisateur n'intervient pas. La mise à jour des calculs est
donc non seulement inutile mais aussi consommatrice.

En revanche, à la fin du traitement il sera la plupart du temps un bon choix
ergonomique d'actualiser car le programme "contourne" le paramétrage
courant, connu de l'utilisateur. Ce dernier ne pensera pas nécessairement à
forcer le recalcul...

Cordialement
Pierre-Yves

Bonjour à tous,

L'optimisation c'est bien, mais à l'origine le problème est que la macro
tournait bien sous OOo et que maintenant il demande un temps d'exécution
sans comparaison. Imaginez, un instant, que cette macro soit déployée sur
des postes d'une organisation équipée de OOo et qui se pose la question de
la migration vers LO. Les premiers résultats de test ne seront pas
favorables à la migration. Alors qu'on vienne dire, il faut l'améliorer
votre macro, etc, juste pour passer à LO, alors que le projet LO s'est
targué d'être non seulement compatible, mais aussi de "sauvegarder les
investissements précédents effectués" dans les versions antérieures de OOo,
là, il y a comme qui dirait, un petit (gros) problème.

Comme l'a souligné Markus, le développeur qui risque de s'occuper du
problème, il faut analyser pourquoi les appels successifs font en sorte de
ralentir l'application - c'est une indication d'un problème dans le code
quelque part. Dire à l'utilisateur qu'il n'a qu'à réécrire tout son code
s'il veut passer à LO n'est pas un argument qui va militer en faveur du
changement...

Alex

Bonjour Alex

Alexander Thurgood wrote

L'optimisation c'est bien, mais à l'origine le problème est que la macro
tournait bien sous OOo et que maintenant il demande un temps d'exécution
sans comparaison.

Nous sommes d'accord...

Alexander Thurgood wrote

Alors qu'on vienne dire, il faut l'améliorer
votre macro, etc, juste pour passer à LO...

Pour ce qui me concerne je n'ai pas dit ça...

Je dis "il faut améliorer votre macro", dans tous les cas, aussi bien pour
rester avec OOo 3.2.1.

D'ailleurs je ne dis pas simplement, "il faut améliorer", je donne aussi les
instructions pour et tente d'expliquer pourquoi.

Alexander Thurgood wrote

Dire à l'utilisateur qu'il n'a qu'à réécrire tout son code
s'il veut passer à LO n'est pas un argument qui va militer en faveur du
changement...

Euh... oui...
Mais nous (me ?) prêter ces propos ne me semble pas de nature à faire
avancer les choses...

Cordialement
Pierre-Yves

Bonjour Pierre-Yves,

Excuse-moi si tu te sentais visé, mais mes remarques concernaient plus un
certain état d'esprit que j'ai pu constater au sein du projet dans certains
secteurs qui m'inquiète, plutôt que tes remarques sur ce point en
particulier.

Nous sommes d'accord qu'il vaut mieux, là où cela est possible, utiliser
les pratiques de programmation optimale, tout comme on a pu avoir des
discussions par ailleurs sur l'utilisation de styles.

Ce que je voulais dire c'est qu'il y a une différence entre la théorie de
l'optimisation, qui est en soi un but tout à fait louable, et le
pragmatisme de tous les jours. Je fais partie de ceux qui pense que l'on
doit d'abord être pragmatique si on veut convaincre les utilisateurs
professionnels et les décideurs (DSI et cie) d'effectuer un changement
vers LO, alors que s'ils utilisent déjà OOo, ils ne sont pas si mal servis,
ou bien s'ils sont sous MSO, de vouloir choisir entre OOo, LO, Symphony, ou
une autre forme d'OOo remballée.

Alex