OVH Cloud OVH Cloud

opération sur un tableau complet en une seule fois?

38 réponses
Avatar
marc.dufresne
bonjour
on peut faire correspondre deux tableaux ex tablo1()=tablo2()
mais peut on effectuer une opération sur un tableau complet comme du genre:
tablo1()=tablo2()+5 (ajouter 5 à la valeur de chaque élément du tablo2). Je
sais que ce que j'ai écrit n'est pas valable mais y aurait-il un moyen
quelconque? En fait trouver une méthode utra rapide pour changer toutes les
valeurs d'un tableau!

merci d'avance

10 réponses

1 2 3 4
Avatar
Jean-Marc
"marc.dufresne" a écrit dans le
message de news:44744f4e$0$12361$
Bonjour à tous et merci pour votre intéret
en fait je veux faire l'affichage d'une photo en commençant par un


fond
uniforme et faire apparaitre l'image petit à petit, donc pour ça


j'utilise
la fonction getDIBits qui me permet de récupérer le tableau des


valeurs de
couleur de chaque pixel (1024*1280*3)(fonction elle assez rapide pour


créer
ce tableau environ 470millisecondes). Je commence par un tableau avec


toutes
les valeurs à zéro par exemple , je l'affiche avec la fonction
setDIBits(fonction encore plus rapide 30millisecondes) puis dans une


boucle
j'incrémente chaque éléments du tableau par 1/5 de la valeur de


l'image
d'origine.
For X = 1 To Lpics
For Y = 1 To Hpics
PicBits2(1, X, Y) = PicBits2(1, X, Y) + PicBits(1, X, Y)


vitcoul
'vitcoul=5 par exemple
PicBits2(2, X, Y) = PicBits2(2, X, Y) + PicBits(2, X, Y)


vitcoul
PicBits2(3, X, Y) = PicBits2(3, X, Y) + PicBits(3, X, Y)


vitcoul
Next Y
Next X
mais ce calcul dans une boucle est trop long 4 à 5 secondes pour


1280*1024
pixels

Alors Jean marc tu dits" On peut si ça en vaut la peine" pour moi ça


vaut la
peine ma sueur n'est pas payée, ce n'est que de l'amusement, ce qui
m'intéresse surtout c'est de trouver une méthode qui est plus rapide


pour
changer la valeur de ce tableau. Malheureusement j'ai aucune


connaissance en
C, mais si tu avais un petit programme très bien commenté(pour pouvoir
l'étudier, le comprendre) je suis preneur, mais s'il y avait des


fonctions
même API que je pourrais manipuler en VB et surtout qui améliorerait


très
sensiblement le calcul, tu parles de 100 à 1000 fois plus rapide. Dans
l'immediat je vais aller voir l'adresse que tu as indiquée.



Je vais voir ce que je peux faire assez rapidement.

--
Jean-marc
Tester mon serveur (VB6) => http://myjmnhome.dyndns.org
"There are only 10 kind of people
those who understand binary and those who don't."
mailto: remove '_no_spam_' ;
Avatar
Vincent Guichard
Bonjour,

Je pense qu'il doit exister des algos plus performants pour faire le
calcul que tu veux faire.

Par exemple, tu refais la division PicBits(1, X, Y) vitcoul pour
chaque passage dans la boucle, alors que cette valeur ne change pas, et
pourrais donc être calculée une fois pour toute (dans une troisième
table). Pour chaque pixel, tu fais donc un accès en lecture à PicBits2,
un accès en lecture à PicBits, une addition et une division.
A cause des arrondis, il est de plus possible que l'image après la
cinquième itération soit différente de l'image initiale.


En première simplification, j'aurais tendance à faire une seule
multiplication sur PicBits, avec un facteur variant de 0 à 1

'coef le facteur variant de 0 à 1, ou de 0.2 à 0.8
'si on affiche la table vide au début et l'image initiale à la fin
For X = 1 To Lpics
For Y = 1 To Hpics
PicBits2(1, X, Y) = PicBits(1, X, Y) * coef
PicBits2(2, X, Y) = PicBits(2, X, Y) * coef
PicBits2(3, X, Y) = PicBits(3, X, Y) * coef
Next Y
Next X

En seconde simplification, je me demanderais si une opération de
combinaison entre un rectangle gris et l'image avec bitblt ne ferais pas
ce que je veux.

Vincent Guichard
Avatar
marc.dufresne
bonsoir

je vais essayé avec une seule opération peut être gagnerais je du temps !
tu as raison après cette boucle je finissait par un affichage de l'image
d'origine.
Je n'ai pas compris ce que tu veux dire avec "une opération de combinaison
entre un rectangle gris et l'image avec bitblt "?

"Vincent Guichard" a écrit dans le message de
news: 447488d4$0$6651$
Bonjour,

Je pense qu'il doit exister des algos plus performants pour faire le
calcul que tu veux faire.

Par exemple, tu refais la division PicBits(1, X, Y) vitcoul pour chaque
passage dans la boucle, alors que cette valeur ne change pas, et pourrais
donc être calculée une fois pour toute (dans une troisième table). Pour
chaque pixel, tu fais donc un accès en lecture à PicBits2, un accès en
lecture à PicBits, une addition et une division.
A cause des arrondis, il est de plus possible que l'image après la
cinquième itération soit différente de l'image initiale.


En première simplification, j'aurais tendance à faire une seule
multiplication sur PicBits, avec un facteur variant de 0 à 1

'coef le facteur variant de 0 à 1, ou de 0.2 à 0.8
'si on affiche la table vide au début et l'image initiale à la fin
For X = 1 To Lpics
For Y = 1 To Hpics
PicBits2(1, X, Y) = PicBits(1, X, Y) * coef
PicBits2(2, X, Y) = PicBits(2, X, Y) * coef
PicBits2(3, X, Y) = PicBits(3, X, Y) * coef
Next Y
Next X

En seconde simplification, je me demanderais si une opération de
combinaison entre un rectangle gris et l'image avec bitblt ne ferais pas
ce que je veux.

Vincent Guichard


Avatar
Jean-Marc
"marc.dufresne" a écrit dans le
message de news:44749d0f$0$29637$
bonsoir

je vais essayé avec une seule opération peut être gagnerais je du


temps !
tu as raison après cette boucle je finissait par un affichage de


l'image
d'origine.



Hello,

La solution avec un seul coeff de 0 à 1 est certainement
la meilleure solution, comme ceci (proposé par Vincent):

For X = 1 To Lpics
For Y = 1 To Hpics
PicBits2(1, X, Y) = PicBits(1, X, Y) * coef
PicBits2(2, X, Y) = PicBits(2, X, Y) * coef
PicBits2(3, X, Y) = PicBits(3, X, Y) * coef
Next Y
Next X

Si tu te décides pour cette méthode, je te fournis la version
dll en C, avec les appels et déclaration VB correspondants.

J'ai fais quelques essais préliminaires, j'obtiens
selon les méthodes un gain variant de 10% (pas grand chose) à
1000% (10 fois plus rapide, carrément bien!).

--
Jean-marc
Tester mon serveur (VB6) => http://myjmnhome.dyndns.org
"There are only 10 kind of people
those who understand binary and those who don't."
mailto: remove '_no_spam_' ;
Avatar
marc.dufresne
Bonsoir plutôt bonne nuit

je n'ai pas encore essayé avec un coefficient, mais je ne comprends pas
comment tu obtiens des gains soit de 10% soit de 1000%, je suppose que ce
n'est pas avec les mêmes méthodes!?

Je suis Ok pour que tu fournisses une dll version C mais il faudra
m'explique comment on s'en sert et surtout si ça ne te dérange pas de me
commenter ta méthode, je tiens à apprendre quelque chose,c'est ça qui
m'intéresse dans la réalisation de mon programe

merci encore et bonne nuit


"Jean-Marc" a écrit dans le message de news:
4474bc1c$0$2131$
"marc.dufresne" a écrit dans le
message de news:44749d0f$0$29637$
bonsoir

je vais essayé avec une seule opération peut être gagnerais je du


temps !
tu as raison après cette boucle je finissait par un affichage de


l'image
d'origine.



Hello,

La solution avec un seul coeff de 0 à 1 est certainement
la meilleure solution, comme ceci (proposé par Vincent):

For X = 1 To Lpics
For Y = 1 To Hpics
PicBits2(1, X, Y) = PicBits(1, X, Y) * coef
PicBits2(2, X, Y) = PicBits(2, X, Y) * coef
PicBits2(3, X, Y) = PicBits(3, X, Y) * coef
Next Y
Next X

Si tu te décides pour cette méthode, je te fournis la version
dll en C, avec les appels et déclaration VB correspondants.

J'ai fais quelques essais préliminaires, j'obtiens
selon les méthodes un gain variant de 10% (pas grand chose) à
1000% (10 fois plus rapide, carrément bien!).

--
Jean-marc
Tester mon serveur (VB6) => http://myjmnhome.dyndns.org
"There are only 10 kind of people
those who understand binary and those who don't."
mailto: remove '_no_spam_' ;



Avatar
marc.dufresne
j'ai oublié j'essaye d'aller sur ton site mais apperemment j'ai toujours
serveur introuvable

"Jean-Marc" a écrit dans le message de news:
4474bc1c$0$2131$
"marc.dufresne" a écrit dans le
message de news:44749d0f$0$29637$
bonsoir

je vais essayé avec une seule opération peut être gagnerais je du


temps !
tu as raison après cette boucle je finissait par un affichage de


l'image
d'origine.



Hello,

La solution avec un seul coeff de 0 à 1 est certainement
la meilleure solution, comme ceci (proposé par Vincent):

For X = 1 To Lpics
For Y = 1 To Hpics
PicBits2(1, X, Y) = PicBits(1, X, Y) * coef
PicBits2(2, X, Y) = PicBits(2, X, Y) * coef
PicBits2(3, X, Y) = PicBits(3, X, Y) * coef
Next Y
Next X

Si tu te décides pour cette méthode, je te fournis la version
dll en C, avec les appels et déclaration VB correspondants.

J'ai fais quelques essais préliminaires, j'obtiens
selon les méthodes un gain variant de 10% (pas grand chose) à
1000% (10 fois plus rapide, carrément bien!).

--
Jean-marc
Tester mon serveur (VB6) => http://myjmnhome.dyndns.org
"There are only 10 kind of people
those who understand binary and those who don't."
mailto: remove '_no_spam_' ;



Avatar
Patrice Henrio
Je viens d'aller sur le site de Jean-Marc. Pas de problème ...


"marc.dufresne" a écrit dans le
message de news: 4474e532$0$24914$
j'ai oublié j'essaye d'aller sur ton site mais apperemment j'ai toujours
serveur introuvable

"Jean-Marc" a écrit dans le message de
news: 4474bc1c$0$2131$
"marc.dufresne" a écrit dans le
message de news:44749d0f$0$29637$
bonsoir

je vais essayé avec une seule opération peut être gagnerais je du


temps !
tu as raison après cette boucle je finissait par un affichage de


l'image
d'origine.



Hello,

La solution avec un seul coeff de 0 à 1 est certainement
la meilleure solution, comme ceci (proposé par Vincent):

For X = 1 To Lpics
For Y = 1 To Hpics
PicBits2(1, X, Y) = PicBits(1, X, Y) * coef
PicBits2(2, X, Y) = PicBits(2, X, Y) * coef
PicBits2(3, X, Y) = PicBits(3, X, Y) * coef
Next Y
Next X

Si tu te décides pour cette méthode, je te fournis la version
dll en C, avec les appels et déclaration VB correspondants.

J'ai fais quelques essais préliminaires, j'obtiens
selon les méthodes un gain variant de 10% (pas grand chose) à
1000% (10 fois plus rapide, carrément bien!).

--
Jean-marc
Tester mon serveur (VB6) => http://myjmnhome.dyndns.org
"There are only 10 kind of people
those who understand binary and those who don't."
mailto: remove '_no_spam_' ;







Avatar
Jean-Marc
"marc.dufresne" a écrit dans le
message de news:4474e532$0$24914$
j'ai oublié j'essaye d'aller sur ton site mais apperemment j'ai


toujours
serveur introuvable



Je reposte pour mémoire:

Le SafeArray (merci François!):
http://users.skynet.be/candide/bench/benchcpm.htm

Un simple test de parité:
http://users.skynet.be/candide/jmn/vb/documents/bench/bench3.htm


--
Jean-marc
Tester mon serveur (VB6) => http://myjmnhome.dyndns.org
"There are only 10 kind of people
those who understand binary and those who don't."
mailto: remove '_no_spam_' ;
Avatar
Jean-Marc
"marc.dufresne" a écrit dans le
message de news:4474e4ee$0$24913$
Bonsoir plutôt bonne nuit

je n'ai pas encore essayé avec un coefficient, mais je ne comprends


pas
comment tu obtiens des gains soit de 10% soit de 1000%, je suppose que


ce
n'est pas avec les mêmes méthodes!?

Je suis Ok pour que tu fournisses une dll version C mais il faudra
m'explique comment on s'en sert et surtout si ça ne te dérange pas de


me
commenter ta méthode, je tiens à apprendre quelque chose,c'est ça qui
m'intéresse dans la réalisation de mon programe



Hello,

Concernant l'écriture et l'utilisation d'une dll, j'ai
écrit un petit tutorial ici:
http://users.skynet.be/candide/jmn/vb/documents/cvb/cetvb.htm

Il renvoie aussi à ce lien, bien utile:
http://rp.developpez.com/vb/tutoriels/dll/

Voici le code source de ma dll

8<------------------------------------------------------

#define export __declspec (dllexport)

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

export void __stdcall GradientTablo(int *PicBits2, int *PicBits, long
nbElem, double coeff);
void __stdcall GradientTablo(int *PicBits2, int *PicBits, long nbElem,
double coeff)
{
long dec;

for(dec = 0;dec<nbElem;dec++)
{
PicBits2[dec] = (long)(PicBits[dec] * coeff);
}
}

8<------------------------------------------------------

Et l'utilisation en VB:

' declarations
Private Declare Sub GradientTablo Lib
"C:JMDvpmtVCquickarrayreleasequickarray.dll" Alias
"" _
(PicBits2 As Long, _
PicBits As Long, _
ByVal nbElem As Long, _
ByVal Coeff As Double)

Const Lpics As Long = 1280
Const Hpics As Long = 1024
Const Sprof As Long = 3
Const Coeff As Long = 0.5
Dim PicBits2(1 To Sprof, 1 To Lpics, 1 To Hpics) As Long
Dim PicBits(1 To Sprof, 1 To Lpics, 1 To Hpics) As Long

Public Sub test2()
Dim t1 As Double, t2 As Double

Debug.Print "start"
t1 = Timer

' PicBits2[dec] = (long)(PicBits[dec] * coeff);
GradientTablo PicBits2(1, 1, 1), PicBits(1, 1, 1), CLng(Lpics *
Hpics * Sprof), 0.5

t2 = Timer

MsgBox t2 - t1
End Sub


Le plus sympa maintenant, les résultats!!

La version en C permet un gain de 500%, c'est à dire que le code est 5
fois plus rapide.

Version VB: en moyenne 0.93 secondes
Version C : en moyenne 0.16 secondes

C'est quand même appréciable!

NOTE: On pourrait gagner encore (ENORMEMENT) en vitesse en se
débarassant de la multiplication par un flottant, qui est
hyper gourmande.
Une astuce serait de se ramener à une suite de divisions par une
puissance de 2, qu'on implémenterait alors comme un simple décalage
à droite (right bit shift, opérateur >> en C), ce qui est des
milliers de fois plus rapide qu'une multiplication par un flottant.

A mon avis, on passerait de 0,16 secondes (160 ms) à moins d'une
dizaine de milliseconde (<10 ms), sans doute même mieux.

Tu as toutes les billes pour le faire maintenant, je pense :-)

Bonne prog!


--
Jean-marc
Tester mon serveur (VB6) => http://myjmnhome.dyndns.org
"There are only 10 kind of people
those who understand binary and those who don't."
mailto: remove '_no_spam_' ;
Avatar
Jean-Marc
"marc.dufresne" a écrit dans le
message de news:4474e4ee$0$24913$
Bonsoir plutôt bonne nuit

je n'ai pas encore essayé avec un coefficient, mais je ne comprends


pas
comment tu obtiens des gains soit de 10% soit de 1000%, je suppose que


ce
n'est pas avec les mêmes méthodes!?

Je suis Ok pour que tu fournisses une dll version C mais il faudra
m'explique comment on s'en sert et surtout si ça ne te dérange pas de


me
commenter ta méthode, je tiens à apprendre quelque chose,c'est ça qui
m'intéresse dans la réalisation de mon programe




Hello,

j'ai fait une petite page web qui résume tout cela,
avec des jolis tableaux et graphiques :-)

Le tout disponible ici:
http://users.skynet.be/candide/bench/bencha/bencharray.htm
et la:
http://myjmnhome.dyndns.org/vb/documents/benchArray/benchArray.htm

--
Jean-marc
Tester mon serveur (VB6) => http://myjmnhome.dyndns.org
"There are only 10 kind of people
those who understand binary and those who don't."
mailto: remove '_no_spam_' ;
1 2 3 4