This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
td9:part2 [2021/11/06 15:00] bmonsuez [Question n°1] |
td9:part2 [2022/11/18 10:48] (current) |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== Partie 2 :Mesuré le temps passé par une fonction ====== | + | ====== Partie 2 : Mesurer le temps passé par une fonction ====== |
[[in204:tds:sujets:td9|TD9]] | [[in204:tds:sujets:td9|TD9]] | ||
Line 37: | Line 37: | ||
La fonction aura le squelette suivant: | La fonction aura le squelette suivant: | ||
<code cpp> | <code cpp> | ||
- | std::pair<std::chrono::high_resolution_clock::duration, int> estimate_time(int n) | + | std::pair<std::chrono::high_resolution_clock::duration, int> estimate_factorial_time(int n) |
{ | { | ||
// Code pour lancer le chronomètre | // Code pour lancer le chronomètre | ||
Line 48: | Line 48: | ||
<hidden Correction> | <hidden Correction> | ||
- | Ceci est assez simple à réaliser en utilisant les fonctions ''std::chrono::high_resolution_clock::now()'' et ''std::make_pair()'' | + | Ceci est assez simple à réaliser en utilisant les fonctions ''std::chrono::high_resolution_clock::now()'' et ''std::make_pair()''. |
+ | |||
+ | <code cpp> | ||
+ | std::pair<std::chrono::high_resolution_clock::duration, long double> estimate_factorial_time(int n) | ||
+ | { | ||
+ | auto starting_time = std::chrono::high_resolution_clock::now(); | ||
+ | auto result = factorial(n); | ||
+ | auto elasped_time = std::chrono::high_resolution_clock::now() - starting_time; | ||
+ | return std::make_pair(elasped_time, result); | ||
+ | } | ||
+ | </code> | ||
</hidden> | </hidden> | ||
Line 54: | Line 65: | ||
===== Question n°2 ===== | ===== Question n°2 ===== | ||
- | Transformer la fonction précédente <code>estimate_time</code> pour qu'elle prenne en argument une fonction arbitraire à un argument et un résultat. | + | Transformer la fonction précédente <code>estimate_time</code> pour qu'elle prenne en argument une fonction arbitraire qui prend un argument et retourne un résultat qui ne sera pas obligatoirement un résultat de type ''long double''. |
Il faudra penser à utiliser un modèle (template) de fonctions. | Il faudra penser à utiliser un modèle (template) de fonctions. | ||
Line 68: | Line 79: | ||
<code cpp> | <code cpp> | ||
template<class Function, class T> | template<class Function, class T> | ||
- | std::pair<std::chrono::high_resolution_clock::duration, long double> estimate_function_time(Function function, T argument) | + | auto estimate_function_time(Function function, T argument) |
{ | { | ||
auto starting_time = std::chrono::high_resolution_clock::now(); | auto starting_time = std::chrono::high_resolution_clock::now(); | ||
Line 85: | Line 96: | ||
<code cpp> | <code cpp> | ||
- | template<class T1, T2> | + | template<class numericalT> |
- | T1 power(T2 x, int y) | + | numericalT power_by_int(numericalT x, int y) |
{ | { | ||
- | T1 result = (T1)1.0 | + | numericalT result = (numericalT)1.0; |
- | while(y-- > 0) | + | while (y-- > 0) |
- | result = result * (T1)x; | + | result *= x; |
- | return result; | + | return result; |
} | } | ||
</code> | </code> | ||
Line 97: | Line 108: | ||
Modifier le code de la fonction pour pouvoir prendre une telle fonction comme paramètre. | Modifier le code de la fonction pour pouvoir prendre une telle fonction comme paramètre. | ||
- | Estimer le temps nécesaire pour calculer par exemple : 1.02 ^ 10000000. | + | __**Remarque**__: il faut penser à utiliser les **packs de paramètres** que nous avons vu dans la première partie du TD. |
+ | |||
+ | <hidden Correction> | ||
+ | Dans le cas présent, comme nous avons aucun, un ou plusieurs paramètres, chacun des paramètres pouvant avoir un type différent. Dans ce cas, nous pouvons remplacer le paramêtre ''T'' de la fonction ''estimate_function_time'' précédenter par un argument correspondant à un pack de paramètres ''...Args''. Et c'est tout ! | ||
+ | |||
+ | template<class Function, class ... Args> | ||
+ | auto estimate_function_time(Function function, Args... arguments) | ||
+ | { | ||
+ | auto starting_time = std::chrono::high_resolution_clock::now(); | ||
+ | auto result = function(arguments...); | ||
+ | auto elasped_time = std::chrono::high_resolution_clock::now() - starting_time; | ||
+ | return std::make_pair(elasped_time, result); | ||
+ | } | ||
+ | |||
+ | </hidden> | ||
+ | |||
+ | Estimer le temps nécesaire pour calculer par exemple : 1.0002 ^ 10000000. | ||
+ | |||
+ | <hidden Correction> | ||
+ | |||
+ | Le code suivant va permettre d'estimer le temps passé à calculer le résultat : | ||
+ | |||
+ | <code cpp> | ||
+ | auto pw = estimate_function_time(power_by_int<long double>, 1.0002, 1000000); | ||
+ | std::cout << "Computing 1.02^1000000=" << pw.second << " in " << pw_10000000.first.count() << " ticks.\n"; | ||
+ | </code> | ||
+ | |||
+ | </hidden> | ||
==== Question n°5 ==== | ==== Question n°5 ==== | ||
- | Créer une fonction nouvelle qui va appeller la fonction <code>estimate_time</code> pour calculer <code>x</code> fois le temps et retourné le temps moyen pour effectuer un "run" de la fonction. | + | Créer une fonction nouvelle qui va appeller la fonction ''estimate_function_time'' pour calculer ''x'' fois le temps nécessaire pour calculer la fonction et qui retourn le temps moyen pour effectuer un "run" de la fonction. |
- | Exécuter cette fonction pour les fonctions <code>power</code> et <code>factorial</code> précédemment définie. | ||
- | ==== Question n°4 ==== | + | Cette fonction aura l'entête suivante : |
- | Que faut-il faire ajouter pour dire au compilateur que la fonction <code>factorial</code> ou que la fonction <code>power</code> peut-être exécutée au moment de l'exécution ? | + | <code cpp> |
+ | template<class Function, class ... Args> | ||
+ | long long mean_function_time(int number_of_runs, Function function, Args... arguments) | ||
+ | { | ||
+ | ... | ||
+ | } | ||
+ | </code> | ||
- | Effectuer la modification. | + | <hidden Correction> |
+ | |||
+ | Il suffit de lancer ''number_of_runs'' fois un appel à ''estimate_function_time'' pour la fonction et les arguments. Ceci donne le code suivant : | ||
+ | |||
+ | <code cpp> | ||
+ | template<class Function, class ... Args> | ||
+ | long long mean_function_time(int number_of_runs, Function function, Args... arguments) | ||
+ | { | ||
+ | long long duration = 0L; | ||
+ | int remaining_runs = number_of_runs; | ||
+ | while (remaining_runs-- > 0) | ||
+ | duration += estimate_function_time(function, arguments...).first.count(); | ||
+ | return duration / (long long)number_of_runs; | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | </hidden> | ||
- | Calculer le temps pris désormais par ces fonctions. | ||
+ | [[.td9:part1|Manipuler un nombre variable de paramètres]] | ||
+ | [[.td9:part3|Exécution à la compilation]] | ||