Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1282 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  intérêt de boost::multi_array ?

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

intérêt de boost::multi_array ?

n°1542908
boulgakov
Posté le 14-04-2007 à 17:24:39  profilanswer
 

Bonjour,
 
J'ai tout un tas de données qui se stockent dans des tableaux pleins à plusieurs dimensions (disons par exemple : un prix qui dépend du pas de temps, du client, du fournisseur, du produit et du pays).
 
Solution C :
 

Code :
  1. double *****prix


 
Beurk. En outre il faut allouer et détruire, j'ai une vingtaine de types de données du même genre : impossible.
 
Solution STL :

Code :
  1. vector<vector<vector<vector<vector<double> > > > prix


 
Re-beurk. Allocation à peine plus chouette qu'en C.
 
Je précise qu'il y a plusieurs types de données différentes, certaines entières d'autres réelles, et pouvant dépendre de 0 à 5 dimensions. Mon exemple du prix ci-dessus correspond au "pire" cas.
 
Solution Boost :

Code :
  1. multi_array<double,5> prix


 
Bien ! Problème : j'ai fait quelques tests sous VC++ 2005 (toutes optimisations à fond, "checked iterators" désactivés). Je fait des boucles pour stocker et lire 10^8 fois soit a) un rand() b) une constante.
 
* Résultats sur les rand() :
 
En 1 dimension (10 éléments), STL ~ Boost.
En 2 dimensions (10*10 = 100 éléments), Boost 2 fois plus lent que STL.  :heink:  
 
* Résultats sur 1 constante :
 
En 1 dimension, Boost 2 fois plus lent que la STL. Là OK, un conteneur multi-dimensions n'est pas forcément super adapté pour un tableau simple.
En 2 dimensions, Boost 8 fois plus lent que la STL  :ouch:  :ouch: Bon, si je teste avec 2*10^6 éléments, l'écart se ressert (Boost 3 fois plus lent) mais bof quoi.
 
Donc je ne comprends pas. boost::multi_array me semblait justement fait pour moi : données dont je connais a priori le nombre de dimensions mais pas la taille de chaque dimension + pas envie d'écrire des horreurs comme vector<vector<vector<... Quel est l'intérêt s'il m'explose mon temps de calcul ? Je ne suis pas en train de me défouler dessus, hein, je voudrais vraiment savoir à quoi sert cette librairie, j'ai sûrement raté quelque chose. En plus je peux écrire :
 

Code :
  1. template<class T> struct Types
  2. {
  3.   typedef vector<vector<vector<vector<vector<T> > > > tab5Dim;
  4. };


 
et garder les perfs de la STL + une syntaxe relativement concise.


Message édité par boulgakov le 14-04-2007 à 17:26:16
mood
Publicité
Posté le 14-04-2007 à 17:24:39  profilanswer
 

n°1542913
0x90
Posté le 14-04-2007 à 18:26:48  profilanswer
 

Spa forcément la meilleure solution, mais pour te réduire l'écriture d'empilement de vecteurs tu peut faire ça :

 
Code :
  1. #include <vector>
  2. #include <iostream>
  3.  
  4. /* Template de base */
  5. template <typename T, int depth>
  6. class metavector : public std::vector<metavector<T, depth-1> > {};
  7. /* Specialisation partielle pour le dernier tableau */
  8. template <typename T>
  9. class metavector<T, 1> : public std::vector<T> {};
  10.  
  11. int main(void) {
  12. /* Tadam ! */
  13. metavector<double, 4> bidule;
  14. bidule.resize(1);
  15. bidule[0].resize(1);
  16. bidule[0][0].resize(1);
  17. bidule[0][0][0].resize(1);
  18. bidule[0][0][0][0] = 42.1337;
  19. std::cout << bidule[0][0][0][0] << std::endl;
  20. }
 

Evidemment faut voir si ton compilo supporte bien la spécialisation partielle, j'utilise que gcc ici, je peut pas test :/
Après peut-être que les valarray peuvent t'aider aussi...

Message cité 1 fois
Message édité par 0x90 le 14-04-2007 à 18:29:09

---------------
Me: Django Localization, Yogo Puzzle, Chrome Grapher, C++ Signals, Brainf*ck.
n°1542923
el muchach​o
Comfortably Numb
Posté le 14-04-2007 à 19:50:14  profilanswer
 

Et en quoi le couple classe + conteneur classique serait inapproprié au problème ?

n°1542933
boulgakov
Posté le 14-04-2007 à 20:36:00  profilanswer
 

el muchacho a écrit :

Et en quoi le couple classe + conteneur classique serait inapproprié au problème ?


 
Ce ne serait pas inapproprié à strictement parler, mais je trouverais quand même assez bizarre d'ajouter une classe à mon code qui encapsulerait juste un tableau multidimensionnel. Si les dimensions n'étaient connues qu'à l'exécution, je ne dis pas (je l'ai déjà fait), mais là... Ajouter des conteneurs propriétaires qui n'encapsulent que l'existant me paraît à éviter. Je n'aime pas trop tomber sur des codes où les gens ont commencé par redéfinir des class Queue et des Pile, par exemple.
 

0x90 a écrit :

Spa forcément la meilleure solution, mais pour te réduire l'écriture d'empilement de vecteurs tu peut faire ça :
 
[...]
 
Evidemment faut voir si ton compilo supporte bien la spécialisation partielle, j'utilise que gcc ici, je peut pas test :/
Après peut-être que les valarray peuvent t'aider aussi...


 
Pas mal du tout. Je n'ai jamais écrit de templates récursifs, je ne risquais pas de trouver ça tout seul. Ta solution m'évite aussi de définir les N types avec des noms comme 'tabNDims', 'tab(N-1)Dims', etc..., ce qui aurait été très moche. Merci !
 
Sinon, j'ai réfléchi et faut avouer qu'il y a quelques trucs pas mal dans boost::multi_array. Genre, on peut définir des vues sur un tableau. Par exemple "vue à 2 dimensions, où les indices 2,3 et 4 de mon tableau X à 5 dimensions sont fixés et où je ne prends que les éléments d'indices pairs sur la 5ème dimension" : comme les itérateurs sont définis sur les vues, c'est compatible avec les algos de la STL et je peux très bien trier ces éléments par ordre croissants en une ligne avec un std:sort, etc etc... Bref, l'intérêt est plutôt de se conformer au modèle de programmation générique de la STL, ce qui ne m'intéresse pas dans le cas présent.
 

n°1542974
el muchach​o
Comfortably Numb
Posté le 15-04-2007 à 02:34:41  profilanswer
 

boulgakov a écrit :

Ce ne serait pas inapproprié à strictement parler, mais je trouverais quand même assez bizarre d'ajouter une classe à mon code qui encapsulerait juste un tableau multidimensionnel. Si les dimensions n'étaient connues qu'à l'exécution, je ne dis pas (je l'ai déjà fait), mais là... Ajouter des conteneurs propriétaires qui n'encapsulent que l'existant me paraît à éviter. Je n'aime pas trop tomber sur des codes où les gens ont commencé par redéfinir des class Queue et des Pile, par exemple.


Non, ce que je dis, c'est qu'à première vue, si on prend ton exemple de tuple hétérogène (un prix qui dépend du pas de temps, du client, du fournisseur, du produit et du pays), on peut/doit faire une classe de ça. Et on met les objects instanciés dans un conteneur standard.

n°1542976
boulgakov
Posté le 15-04-2007 à 03:45:56  profilanswer
 

el muchacho a écrit :

Non, ce que je dis, c'est qu'à première vue, si on prend ton exemple de tuple hétérogène (un prix qui dépend du pas de temps, du client, du fournisseur, du produit et du pays), on peut/doit faire une classe de ça. Et on met les objects instanciés dans un conteneur standard.


 
Euh... bah non. J'ai pas dû être clair. C'est un code numérique, hein, j'ai un peu instancié pour que ça parle aux gens mais mon temps, mes clients,... ce sont juste des indices entiers. Pourquoi je créerais une classe ?
 

Code :
  1. class Prix {
  2. private :
  3.   metavector<double, 5> valeurs;
  4. public :
  5.   getPrix(const unsigned int client, const unsigned int fournisseur, ...)
  6.     {
  7.       return valeurs[client][fournisseur]...;
  8.     }
  9. };


 
Pas super utile, voire même nuisible.
 

n°1543006
el muchach​o
Comfortably Numb
Posté le 15-04-2007 à 13:01:31  profilanswer
 

Mais non. C'est du n'importe quoi, là.  
 
Ce à quoi je pensais, c'était plutôt qq chose comme:

Code :
  1. class truc {
  2.   int client, fournisseur, produit, pays;
  3. }
  4. vector<pair<int prix, truc maStruc> >


par exemple.
 
Mais si ça se trouve, ça n'est pas ce que tu veux faire. Tu veux p-ê faire des recherches sur d'autres colonnes ? Pour l'instant, tout ce que je vois, c'est un problème extrêmement mal modélisé, l'équivalent d'une base de données avec toutes les données en bordel dans une seule table, et donc une solution qui ne marchera probablement pas avec un nombre conséquent de données.
Mais comme tu n'es pas disert sur ce que tu veux réellement faire, on ne peut pas vraiment aider, on ne peut que faire des supputations.


Message édité par el muchacho le 15-04-2007 à 13:01:55
n°1543008
Taz
bisounours-codeur
Posté le 15-04-2007 à 13:07:14  profilanswer
 

On peut avoir ton code de benchmark ?

n°1543013
boulgakov
Posté le 15-04-2007 à 13:48:59  profilanswer
 

Taz a écrit :

On peut avoir ton code de benchmark ?


 
Ouaip, avec plaisir, si ça se trouve je tire les mauvaises conclusions du mauvais test. J'ai la flemme de mettre au propre, par contre. Le test 1 dim et le test 2 dims se suivent dans le main(). En 2 dimensions, je sais que t'attaque toujours la diagonale de la matrice ce qui pourrait être un biais, mais j'ai fait quelques variantes et cela ne change rien.
 

Code :
  1. #include <iostream>
  2. #include <ctime>
  3. #include <vector>
  4. #include <exception>
  5. #include <algorithm>
  6. #include <cstdlib>
  7. #include "boost/multi_array.hpp"
  8. using namespace boost;
  9. using namespace std;
  10. const unsigned int NB_TESTS = 10;
  11. const long unsigned int NB_ITERATIONS = 10000000;
  12. const unsigned int LONGUEUR = 10;
  13. double recipient = 0.0;
  14. // Test 1 dim
  15. template<typename T> double test(T &tableau)
  16. {
  17. long unsigned int i = 0;
  18. unsigned int indiceTab = 0;
  19. time_t time1 = clock();
  20. for ( i = 0; i < NB_ITERATIONS; i++ )
  21. {
  22.  indiceTab = i % LONGUEUR;
  23.  tableau[indiceTab] = 10.0; // Ecriture
  24.  recipient = tableau[indiceTab]; // Lecture
  25. }
  26. time_t time2 = clock();
  27. return (time2 - time1) / 1000.0;
  28. }
  29. // Test 2 dim
  30. template<typename T> double test2(T &tableau)
  31. {
  32. long unsigned int i = 0;
  33. unsigned int indiceTab = 0;
  34. time_t time1 = clock();
  35. for ( i = 0; i < NB_ITERATIONS; i++ )
  36. {
  37.  indiceTab = i % LONGUEUR;
  38.  tableau[indiceTab][indiceTab] = 10.0; // Ecriture
  39.  recipient = tableau[indiceTab][indiceTab]; // Lecture
  40. }
  41. time_t time2 = clock();
  42. return (time2 - time1) / 1000.0;
  43. }
  44. int main()
  45. {
  46. try
  47. {
  48.  srand( (unsigned)time( NULL ) );
  49.  cout << " *** Tests 1 Dimension " << endl << endl;
  50.  vector<vector<double>> resultats(3);
  51.  multi_array<double, 1> tabBoost(extents[LONGUEUR]);
  52.  vector<double> tabSTL(LONGUEUR);
  53.  double *tabC = new double[LONGUEUR];
  54.  for (unsigned int iTest = 0; iTest < NB_TESTS; iTest++ )
  55.  {
  56.   double resSTL = test(tabSTL);
  57.   double resC = test(tabC);
  58.   double resBoost = test(tabBoost);
  59.   resultats[0].push_back(resSTL);
  60.   resultats[1].push_back(resC);
  61.   resultats[2].push_back(resBoost);
  62.   cout << "STL : " << resSTL << " s." << endl;
  63.   cout << "C : " << resC << " s." << endl;
  64.   cout << "multiarray : " << resBoost << " s." << endl;
  65.   cout << endl;
  66.  }
  67.  delete [] tabC;
  68.  cout << "Moyenne STL : " << accumulate(resultats[0].begin(), resultats[0].end(), 0.0) / NB_TESTS << endl;
  69.  cout << "Moyenne C : " << accumulate(resultats[1].begin(), resultats[1].end(), 0.0) / NB_TESTS << endl;
  70.  cout << "Moyenne Boost : " << accumulate(resultats[2].begin(), resultats[2].end(), 0.0) / NB_TESTS << endl;
  71.  cout << endl << " *** Tests 2 Dimensions " << endl;
  72.  vector<vector<double> >  resultats2(3);
  73.  multi_array<double, 2> tabBoost2(extents[LONGUEUR][LONGUEUR]);
  74.  vector<vector<double> > tabSTL2(LONGUEUR, vector<double>(LONGUEUR));
  75.  double **tabC2 = new double *[LONGUEUR];
  76.  for ( unsigned int l = 0; l < LONGUEUR; l++ )
  77.  {
  78.   tabC2[l] = new double[LONGUEUR];
  79.  }
  80.  for (unsigned int iTest2 = 0; iTest2 < NB_TESTS; iTest2++ )
  81.  {
  82.   double resSTL2 = test2(tabSTL2);
  83.   double resC2 = test2(tabC2);
  84.   double resBoost2 = test2(tabBoost2);
  85.   resultats2[0].push_back(resSTL2);
  86.   resultats2[1].push_back(resC2);
  87.   resultats2[2].push_back(resBoost2);
  88.   cout << "STL : " << resSTL2 << " s." << endl;
  89.   cout << "C : " << resC2 << " s." << endl;
  90.   cout << "multiarray : " << resBoost2 << " s." << endl;
  91.   cout << endl;
  92.  }
  93.  cout << "Moyenne STL : " << accumulate(resultats2[0].begin(), resultats2[0].end(), 0.0) / NB_TESTS << endl;
  94.  cout << "Moyenne C : " << accumulate(resultats2[1].begin(), resultats2[1].end(), 0.0) / NB_TESTS << endl;
  95.  cout << "Moyenne Boost : " << accumulate(resultats2[2].begin(), resultats2[2].end(), 0.0) / NB_TESTS << endl;
  96.  for ( unsigned int l = 0; l < LONGUEUR; l++ )
  97.  {
  98.   delete [] tabC2[l];
  99.  }
  100.  delete [] tabC2;
  101. }
  102. catch(exception &e)
  103. {
  104.  cout << e.what() << endl;
  105. }
  106. }


 
Edit - Les résultats sur les 2 dimensions :
 
**
Moyenne STL : 0.0972
Moyenne C : 0.0828
Moyenne Boost : 1.0731
**


Message édité par boulgakov le 15-04-2007 à 13:53:26
n°1543021
Taz
bisounours-codeur
Posté le 15-04-2007 à 14:52:24  profilanswer
 

Code :
  1. #include <iostream>
  2. #include <ctime>
  3. #include <vector>
  4. #include <exception>
  5. #include <algorithm>
  6. #include <cstdlib>
  7. #include <boost/multi_array.hpp>
  8. #include <boost/timer.hpp>
  9. using namespace boost;
  10. using namespace std;
  11. const unsigned int NB_TESTS = 100;
  12. const long unsigned int NB_ITERATIONS = 10000000;
  13. const unsigned int LONGUEUR = 10;
  14. template<typename Array>
  15. double do_test(Array &a, double (&f)(Array &a))
  16. {
  17.   timer t;
  18.   for (unsigned i = 0; i != NB_TESTS; ++i)
  19.     f(a);
  20.   return t.elapsed();
  21. }
  22. // Test 1 dim
  23. template<typename T> double test(T &tableau)
  24. {
  25.   timer t;
  26.   long unsigned int i = 0;
  27.   unsigned int indiceTab = 0;
  28.   for ( i = 0; i < NB_ITERATIONS; i++ )
  29.     {
  30.       indiceTab = i % LONGUEUR;
  31.       tableau[indiceTab] *= 10.0;
  32.     }
  33.   return t.elapsed();
  34. }
  35. // Test 2 dim
  36. template<typename T> double test2(T &tableau)
  37. {
  38.   timer t;
  39.   long unsigned int i = 0;
  40.   unsigned int indiceTab = 0;
  41.   for ( i = 0; i < NB_ITERATIONS; i++ )
  42.     {
  43.       indiceTab = i % LONGUEUR;
  44.       tableau[indiceTab][indiceTab] *= 10.0;
  45.     }
  46.   return t.elapsed();
  47. }
  48. int main()
  49. {
  50.   try
  51.     {
  52.       srand( (unsigned)time( NULL ) );
  53.       multi_array<double, 1> tabBoost(extents[LONGUEUR]);
  54.       vector<double> tabSTL(LONGUEUR);
  55.       double *tabC = new double[LONGUEUR];
  56.       cout << "[1] STL   " << do_test(tabSTL, test) << '\n'
  57.    << "[1] C     " << do_test(tabC, test) << '\n'
  58.    << "[1] Boost " << do_test(tabBoost, test) << '\n';
  59.       delete [] tabC;
  60.       multi_array<double, 2> tabBoost2(extents[LONGUEUR][LONGUEUR]);
  61.       vector<vector<double> > tabSTL2(LONGUEUR, vector<double>(LONGUEUR));
  62.       double **tabC2 = new double *[LONGUEUR];
  63.       for ( unsigned int l = 0; l < LONGUEUR; l++ )
  64. {
  65.   tabC2[l] = new double[LONGUEUR];
  66. }
  67.       cout << "[2] STL   " << do_test(tabSTL2, test2) << '\n'
  68.    << "[2] C     " << do_test(tabC2, test2) << '\n'
  69.    << "[2] Boost " << do_test(tabBoost2, test2) << '\n';
  70.       for ( unsigned int l = 0; l < LONGUEUR; l++ )
  71. {
  72.   delete [] tabC2[l];
  73. }
  74.       delete [] tabC2;
  75.     }
  76.   catch(exception &e)
  77.     {
  78.       cout << e.what() << endl;
  79.     }
  80. }

en nettoyant un peu et en simplifiant :
[1] STL   15.89
[1] C     15.88
[1] Boost 18.51
[2] STL   21.45
[2] C     20.45
[2] Boost 24.43

mood
Publicité
Posté le 15-04-2007 à 14:52:24  profilanswer
 

n°1543023
Taz
bisounours-codeur
Posté le 15-04-2007 à 14:58:27  profilanswer
 

et pour la petite histoire, avec une allocation dynamique de tableau (vrai tableau contigüe), ça donne :
[2] STL   21.44
[2] C     20.42
[2] Ca    19.44
[2] Boost 23.51

n°1543026
Taz
bisounours-codeur
Posté le 15-04-2007 à 15:20:59  profilanswer
 

petite analyse de l'assembler ppc du code précédent, et plus précisément sur la boucle :
 

Code :
  1. _Z4testIN5boost11multi_arrayIdLj1ESaIdEEEEdRT_
  2. double test<boost::multi_array<double, 1u, std::allocator<double> > >(boost::multi_array<double, 1u, std::allocator<double> >&
  3. 882 .L141:
  4. 883         mulhwu 0,9,10
  5. 884         srwi 0,0,3
  6. 885         mulli 0,0,10
  7. 886         subf 0,0,9
  8. 887         addi 9,9,1
  9. 888         mullw 0,0,8
  10. 889         slwi 0,0,3
  11. 890         lfdx 0,11,0
  12. 891         fmul 0,0,13
  13. 892         stfdx 0,11,0
  14. 893         bdnz .L141
  15. _Z4testIPdEdRT_
  16. test<double*>(double*& )
  17. 1392 .L207:
  18. 1393         mulhwu 9,11,0
  19. 1394         srwi 9,9,3
  20. 1395         mulli 9,9,10
  21. 1396         subf 9,9,11
  22. 1397         addi 11,11,1
  23. 1398         slwi 9,9,3
  24. 1399         lfdx 0,29,9
  25. 1400         fmul 0,0,13
  26. 1401         stfdx 0,29,9
  27. 1402         bdnz .L207
  28. _Z4testISt6vectorIdSaIdEEEdRT
  29. double test<std::vector<double, std::allocator<double> > >(std::vector<double, std::allocator<double> >& )
  30. 1528 .L219:
  31. 1529         mulhwu 9,11,0
  32. 1530         srwi 9,9,3
  33. 1531         mulli 9,9,10
  34. 1532         subf 9,9,11
  35. 1533         addi 11,11,1
  36. 1534         slwi 9,9,3
  37. 1535         lfdx 0,29,9
  38. 1536         fmul 0,0,13
  39. 1537         stfdx 0,29,9
  40. 1538         bdnz .L219
  41. double test2<boost::multi_array<double, 2u, std::allocator<double> > >(boost::multi_array<double, 2u, std::allocator<double> >& )
  42. _Z5test2IN5boost11multi_arrayIdLj2ESaIdEEEEdRT
  43. 1669 .L231:
  44. 1670         mulhwu 0,10,6
  45. 1671         srwi 0,0,3
  46. 1672         mulli 9,0,10
  47. 1673         subf 0,9,10
  48. 1674         addi 10,10,1
  49. 1675         mullw 9,0,7
  50. 1676         mullw 11,0,5
  51. 1677         slwi 9,9,3
  52. 1678         slwi 11,11,3
  53. 1679         add 9,8,9
  54. 1680         lfdx 0,9,11
  55. 1681         fmul 0,0,13
  56. 1682         stfdx 0,9,11
  57. 1683         bdnz .L231
  58. double test2<double (*) [10]>(double (*& ) [10])
  59. _Z5test2IPA10_dEdRT_
  60. 1809 .L243:
  61. 1810         mulhwu 0,10,8
  62. 1811         srwi 0,0,3
  63. 1812         mulli 9,0,10
  64. 1813         subf 0,9,10
  65. 1814         addi 10,10,1
  66. 1815         mulli 9,0,80
  67. 1816         slwi 11,0,3
  68. 1817         add 9,29,9
  69. 1818         lfdx 0,11,9
  70. 1819         fmul 0,0,13
  71. 1820         stfdx 0,11,9
  72. 1821         bdnz .L243
  73. double test2<double**>(double**& )
  74. _Z5test2IPPdEdRT_
  75. 1947 .L255:
  76. 1948         mulhwu 0,8,7
  77. 1949         srwi 0,0,3
  78. 1950         mulli 9,0,10
  79. 1951         subf 0,9,8
  80. 1952         addi 8,8,1
  81. 1953         slwi 9,0,2
  82. 1954         slwi 10,0,3
  83. 1955         lwzx 11,9,29
  84. 1956         lfdx 0,10,11
  85. 1957         fmul 0,0,13
  86. 1958         stfdx 0,10,11
  87. 1959         bdnz .L255
  88. double test2<std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > > >(std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >& )
  89. _Z5test2ISt6vectorIS0_IdSaIdEESaIS2_EEEdRT_
  90. 2086         mulhwu 0,8,7
  91. 2087         srwi 0,0,3
  92. 2088         mulli 9,0,10
  93. 2089         subf 0,9,8
  94. 2090         addi 8,8,1
  95. 2091         mulli 9,0,12
  96. 2092         slwi 10,0,3
  97. 2093         lwzx 11,9,29
  98. 2094         lfdx 0,10,11
  99. 2095         fmul 0,0,13
  100. 2096         stfdx 0,10,11
  101. 2097         bdnz .L267


 
On constate que les codes sont extrêment voisins quand ils ne sont pas rigoureusement identiques. La seule différence est sur le calcul d'index : tantôt des shift quand c'est possible, tantôt des multiplication.
 
Dans le test a 2D, cette différence slwi/mulli est la seule entre les méthodes STL et et C. La différence de vitesse de cette instruction se sent sur 10**8 exécutions.
 
Pour moi la différence est faible, le plus lent l'étant de 20% par rapport au plus rapide.

n°1543031
boulgakov
Posté le 15-04-2007 à 16:13:19  profilanswer
 

Taz a écrit :

en nettoyant un peu et en simplifiant :
[1] STL   15.89
[1] C     15.88
[1] Boost 18.51
[2] STL   21.45
[2] C     20.45
[2] Boost 24.43


 
J'ai dû instancier explicitement les fonctions pour que VC++ avale ton code
 

Code :
  1. do_test(tabSTL, test<vector<double>> )
  2. etc etc


 
et j'obtiens :
 
[1] STL   9.985
[1] C     68.796  :heink: (Là, j'ai relancé plusieurs fois et même installé le "Service Pack" en désespoir de cause mais rien n'y fait)
[1] Boost 17.375
[2] STL   11.515
[2] C     10.235
[2] Boost 43.515
 
Conclusion 1 : mon problème vient du compilo, pas de multi_array. Conclusion 2 : j'ai tous les éléments et je n'ai plus qu'à prendre une option, on verra ça plus tard. Il fait quand même un poil beau dehors, je vais pas passer mon WE là-dessus.  
 
Merci  bcp !


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  intérêt de boost::multi_array ?

 

Sujets relatifs
[résolu][boost::thread] thread à partir d'une fonction à argument?Requête multi let join
Multi Requete AjaxPHP 4/5 -> Array (pas de liste ?) [Résolu]
Double tri dans un Array pour un classement[VBA pour Excel] Multi Filtre
index multi champ vs index simple champAucun intérêt...
Boost::SpiritWebBrowser en MTA (Multi Threaded apartment)
Plus de sujets relatifs à : intérêt de boost::multi_array ?


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR