[{"data":1,"prerenderedAt":7488},["ShallowReactive",2],{"tag-posts-performance":3},[4,3322,4586,6285],{"id":5,"title":6,"author":7,"body":8,"category":3234,"categorySlug":3235,"date":3236,"description":45,"excerpt":3237,"extension":3310,"location":3311,"meta":3312,"navigation":294,"path":3313,"published":294,"seo":3314,"slug":3315,"stem":3316,"tags":3317,"timeToRead":1384,"__hash__":3321},"posts\u002Fposts\u002FProgrammation\u002F2011-01-25-qt-performance-de-l-utilisation-de-qsharedpointer.md","C++\u002FQt - Performance de l'utilisation de QSharedPointer","Ulrich Vandenhekke",{"type":9,"value":10,"toc":3227},"minimark",[11,16,28,55,64,135,139,143,148,162,173,180,184,206,234,364,371,381,387,433,439,465,476,490,521,540,597,610,616,625,692,702,708,754,777,783,926,946,954,971,974,1127,1150,1157,1230,1234,1237,1240,1544,1547,1825,1828,1834,1837,1840,1963,1992,1996,2007,2027,2041,2045,2054,2062,2211,2226,2244,2339,2342,2345,2377,2381,2387,2401,2404,2408,2415,2418,2432,2435,2455,2458,2472,2476,2481,2490,2493,2503,2627,2697,2701,2704,2726,2730,2736,2800,2804,2811,2817,2858,2861,2918,2922,2925,3029,3035,3038,3041,3045,3052,3069,3223],[12,13,15],"h3",{"id":14},"présentation","Présentation",[17,18,19,23,24,27],"p",{},[20,21,22],"em",{},"Qt"," est un framework orienté objet écrit en C++ et permettant de faire\ndes interfaces graphiques. Ce framework est utilisé par le projet ",[20,25,26],{},"KDE","\ndepuis ses débuts pour en faire un environnement de bureau très complet.",[17,29,30,32,33,36,48,49,51,52,54],{},[20,31,22],{}," fournit un ensemble de pointeur ",[20,34,35],{},"intelligent",[37,38,39],"sup",{},[40,41,47],"a",{"href":42,"ariaDescribedBy":43,"dataFootnoteRef":45,"id":46},"#user-content-fn-1",[44],"footnote-label","","user-content-fnref-1","1"," permettant\nde gérer plus facilement la mémoire. Le but est alors de ne plus avoir à\nsupprimer des objets. La suppression se fera soit par un pointeur\n",[20,50,35],{}," soit par le système de hiérarchie d'objet existant en ",[20,53,22],{},"\n(l'objet père qui supprime l'ensemble des objets fils qui lui sont\nrattachés).",[17,56,57,59,60,63],{},[20,58,22],{}," propose l'ensemble des pointeurs ",[20,61,62],{},"intelligents"," suivants:",[65,66,67,96,110,118],"ul",{},[68,69,70,76,77,82,83,86,87,95],"li",{},[40,71,75],{"href":72,"rel":73},"http:\u002F\u002Fdoc.qt.nokia.com\u002F4.6\u002Fqshareddatapointer.html",[74],"nofollow","QSharedDataPointer"," \u002F ",[40,78,81],{"href":79,"rel":80},"http:\u002F\u002Fdoc.qt.nokia.com\u002F4.6\u002Fqshareddata.html",[74],"QSharedData"," : ces deux classes\nutilisées ensemble permettent d'écrire un objet avec partage\nimplicite. Cela signifie que l'objet fonctionnera comme la classe\n",[20,84,85],{},"QString",". Tant que l'objet est copié, passé en paramètre, ....\nl'objet n'est pas dupliqué (tous les objets pointes vers le même\nespace mémoire). Au moment où l'objet est modifié, l'objet est\ndupliqué. C'est ce qu'on appelle le COW",[37,88,89],{},[40,90,94],{"href":91,"ariaDescribedBy":92,"dataFootnoteRef":45,"id":93},"#user-content-fn-2",[44],"user-content-fnref-2","2",".",[68,97,98,76,103,106,107,109],{},[40,99,102],{"href":100,"rel":101},"http:\u002F\u002Fdoc.qt.nokia.com\u002F4.6\u002Fqexplicitlyshareddatapointer.html",[74],"QExplictlySharedDataPointer",[40,104,81],{"href":79,"rel":105},[74]," :\nQExplicitlySharedDataPointer est une variante de QSharedDataPointer.\nCe pointeur ",[20,108,35],{},", comme son nom l'indique, est détaché\nuniquement lorsque la méthode detach() est appelée explicitement.\nCette classe permet de faire des objets qui fonctionnent comme des\npointeurs mais qui sont utilisés sans la notion de pointeur (le *).\nLa suppression des données partagées se fait donc quand tous les\nobjets ne sont plus utilisés.",[68,111,112,117],{},[40,113,116],{"href":114,"rel":115},"http:\u002F\u002Fdoc.qt.nokia.com\u002F4.6\u002Fqscopedpointer.html",[74],"QScopedPointer"," : Ce pointeur est le plus simple. Il permet de\ndéclarer un pointeur sur le tas et s'occupe de la destruction de\nl'objet, lorsque le programme sort de la portée du bloc. Cela permet\nde ne plus se soucier de la libération du pointeur dans les cas\nd'erreur (exception, retour avant la fin de la fonction car le\nfichier n'a pu être ouvert, ...).",[68,119,120,125,126,134],{},[40,121,124],{"href":122,"rel":123},"http:\u002F\u002Fdoc.qt.nokia.com\u002F4.6\u002Fqsharedpointer.html",[74],"QSharedPointer"," : Le pointeur dont on parlera dans la suite de ce\nbillet. Il permet de partager non plus des données (comme le fait\nQSharedData) mais de partager un pointeur",[37,127,128],{},[40,129,133],{"href":130,"ariaDescribedBy":131,"dataFootnoteRef":45,"id":132},"#user-content-fn-3",[44],"user-content-fnref-3","3",". Nous allons voir\ndans la suite du billet, comment simplement utiliser ce pointeur, et\nles performances de ce pointeur par rapport à un pointeur standard.",[12,136,138],{"id":137},"sommaire","Sommaire",[12,140,142],{"id":141},"utilisation-de-qsharedpointer","Utilisation de QSharedPointer",[144,145,147],"h4",{"id":146},"a-quoi-sert-il","A quoi sert-il ?",[17,149,150,151,154,155,157,158,161],{},"L'objet ",[152,153,124],"code",{}," fait partie des pointeurs ",[20,156,62],{},". Ces\npointeurs permettent de gérer automatiquement la libération de la\nmémoire (plus besoin de faire ",[152,159,160],{},"delete ptr;"," quand le pointeur n'est plus\nutilisé) tout en restant utilisable comme un pointeur normal.",[17,163,164,166,167,169,170,172],{},[152,165,124],{}," fonctionne par comptage de référence. Après la\ndéclaration, à chaque affectation, on augmente le compteur de référence,\nlorsqu'on quitte la portée du bloc, on décrémente le compteur de\nréférence. ",[152,168,124],{}," détruit donc automatiquement le pointeur\nquand il n'existe plus aucune référence vers ce pointeur.\n",[152,171,124],{}," vient donc comme une encapsulation de notre pointeur.",[17,174,175],{},[176,177],"img",{"alt":178,"src":179},"QSharedPointer vers la même adresse","\u002FProgrammation\u002Fqt-performance-de-l-utilisation-de-qsharedpointer\u002FQSharedPointer1.png",[144,181,183],{"id":182},"comment-lutiliser","Comment l'utiliser ?",[17,185,186,187,190,191,194,195,198,199,202,203,205],{},"La déclaration d'un pointeur en C, se fait en écrivant ",[152,188,189],{},"MyObject*",". La\nsyntaxe en utilisant un QSharedPointer se fait en écrivant\n",[152,192,193],{},"QSharedPointer\u003CMyObject>",". Par la suite dans le programme,\nl'utilisation du pointeur ",[152,196,197],{},"QSharedObject"," se fera de la même manière\nqu'un pointeur C. (Avec l'opérateur ",[152,200,201],{},"->"," pour appeler un membre, une\nméthode, ...) . Appelons dans la suite pointeur C, les pointeurs\nstandards et ",[152,204,124],{},", le pointeur intelligent.",[17,207,208,209,211,212,215,216,218,219,221,222,225,226,95],{},"Afin d'éviter d'avoir un pointeur normal pouvant être supprimé à tout\nmoment dans l'application, lors de l'utilisation de ",[152,210,124],{},", il\nne faut utiliser le pointeur C résultant du ",[152,213,214],{},"new"," que pour la création\ndu ",[152,217,124],{},". On peut donc directement créer le ",[152,220,124],{},"\nen utilisant le constructeur ",[152,223,224],{},"QSharedPointer ( T * ptr )"," qui prend en\nparamètre le pointeur C. C'est entre ces parenthèses que nous allons\ncréer le pointeur C",[37,227,228],{},[40,229,233],{"href":230,"ariaDescribedBy":231,"dataFootnoteRef":45,"id":232},"#user-content-fn-4",[44],"user-content-fnref-4","4",[235,236,240],"pre",{"className":237,"code":238,"language":239,"meta":45,"style":45},"language-cpp shiki shiki-themes one-dark-pro","{\n    \u002F\u002F Création du pointeur intelligent à partir d'un pointeur normal.\n    QSharedPointer\u003CMyObject> ptr(new MyObject());\n\n    \u002F\u002F Utilisation du pointeur intelligent comme un pointeur normal.\n    if (ptr)\n    {\n        ptr->setMembre(maValeur);\n    }\n\n    \u002F\u002F Appel d'une méthode utilisant ce pointeur\n    maMethode(ptr);\n}\n","cpp",[152,241,242,251,258,289,296,302,311,317,332,338,343,349,358],{"__ignoreMap":45},[243,244,247],"span",{"class":245,"line":246},"line",1,[243,248,250],{"class":249},"sn6KH","{\n",[243,252,254],{"class":245,"line":253},2,[243,255,257],{"class":256},"sV9Aq","    \u002F\u002F Création du pointeur intelligent à partir d'un pointeur normal.\n",[243,259,261,264,268,271,274,278,281,283,286],{"class":245,"line":260},3,[243,262,263],{"class":249},"    QSharedPointer",[243,265,267],{"class":266},"seHd6","\u003C",[243,269,270],{"class":249},"MyObject",[243,272,273],{"class":266},">",[243,275,277],{"class":276},"sVbv2"," ptr",[243,279,280],{"class":249},"(",[243,282,214],{"class":266},[243,284,285],{"class":276}," MyObject",[243,287,288],{"class":249},"());\n",[243,290,292],{"class":245,"line":291},4,[243,293,295],{"emptyLinePlaceholder":294},true,"\n",[243,297,299],{"class":245,"line":298},5,[243,300,301],{"class":256},"    \u002F\u002F Utilisation du pointeur intelligent comme un pointeur normal.\n",[243,303,305,308],{"class":245,"line":304},6,[243,306,307],{"class":266},"    if",[243,309,310],{"class":249}," (ptr)\n",[243,312,314],{"class":245,"line":313},7,[243,315,316],{"class":249},"    {\n",[243,318,320,324,326,329],{"class":245,"line":319},8,[243,321,323],{"class":322},"sU0A5","        ptr",[243,325,201],{"class":249},[243,327,328],{"class":276},"setMembre",[243,330,331],{"class":249},"(maValeur);\n",[243,333,335],{"class":245,"line":334},9,[243,336,337],{"class":249},"    }\n",[243,339,341],{"class":245,"line":340},10,[243,342,295],{"emptyLinePlaceholder":294},[243,344,346],{"class":245,"line":345},11,[243,347,348],{"class":256},"    \u002F\u002F Appel d'une méthode utilisant ce pointeur\n",[243,350,352,355],{"class":245,"line":351},12,[243,353,354],{"class":276},"    maMethode",[243,356,357],{"class":249},"(ptr);\n",[243,359,361],{"class":245,"line":360},13,[243,362,363],{"class":249},"}\n",[17,365,366,367,370],{},"Lorsque l'on quitte le bloc, si le comptage de référence tombe à 0, on\nsupprime le pointeur. A l'intérieur de ",[152,368,369],{},"maMethode()"," le nombre de\nréférence sera passé à 2. Si la méthode utilise le pointeur mais ne\nl'assigne nul part, le nombre de référence devrait être retombé à 1 et\ndonc ici sera décrémenté à 0.",[17,372,373,374,376,377,380],{},"Si par contre, ",[152,375,369],{}," fait des opérations d'assignation de ",[152,378,379],{},"ptr","\net conserve une copie, le comptage ne tombera pas à 0 tant que l'objet\nrestera utilisé (assigné) ailleurs.",[17,382,383,384,386],{},"Regardons un exemple de ",[152,385,369],{}," :",[235,388,390],{"className":237,"code":389,"language":239,"meta":45,"style":45},"void maMethode(QSharedPointer\u003CMyObject> ptr)\n{\n    ptr->setMembre2(maValeur);\n",[152,391,392,417,421],{"__ignoreMap":45},[243,393,394,397,400,402,404,406,408,411,414],{"class":245,"line":246},[243,395,396],{"class":266},"void",[243,398,399],{"class":276}," maMethode",[243,401,280],{"class":249},[243,403,124],{"class":322},[243,405,267],{"class":249},[243,407,270],{"class":322},[243,409,410],{"class":249},"> ",[243,412,379],{"class":413},"s_ZVi",[243,415,416],{"class":249},")\n",[243,418,419],{"class":245,"line":253},[243,420,250],{"class":249},[243,422,423,426,428,431],{"class":245,"line":260},[243,424,425],{"class":322},"    ptr",[243,427,201],{"class":249},[243,429,430],{"class":276},"setMembre2",[243,432,331],{"class":249},[17,434,435,436,438],{},"Au début du bloc, ici le comptage de référence est à 2 et sera\ndécrémenté à la sortie de la méthode. On peut modifier les membres de\n",[152,437,379],{},", et dans ce cas pas de changement du comptage de référence.",[235,440,442],{"className":237,"code":441,"language":239,"meta":45,"style":45},"    this->monPtr = ptr;\n}\n",[152,443,444,461],{"__ignoreMap":45},[243,445,446,449,451,455,458],{"class":245,"line":246},[243,447,448],{"class":322},"    this",[243,450,201],{"class":249},[243,452,454],{"class":453},"sVyAn","monPtr",[243,456,457],{"class":266}," =",[243,459,460],{"class":249}," ptr;\n",[243,462,463],{"class":245,"line":253},[243,464,363],{"class":249},[17,466,467,468,471,472,475],{},"Au contraire, on peut également l'assigner à un autre objet. Dans ce cas\nle comptage de référence de cet objet passera à 3. A la sortie de la\nméthode il sera décrémenté et passera alors à 2. L'objet ne sera pas\nsupprimé tant qu'on ne fera pas un ",[152,469,470],{},"this->monPtr.clear()"," ou que ",[152,473,474],{},"this","\nne sera pas détruit.",[17,477,478,479,481,482,485,486,489],{},"Si on veut garder une référence d'un pointeur mais qu'on ne souhaite pas\nque celle-ci incrémente le nombre de référence du ",[152,480,124],{},", il\nest possible de créer un pointeur ",[20,483,484],{},"faible",". Ce pointeur passe par\nl'objet ",[152,487,488],{},"QWeakPointer",". Pour obtenir ce type de pointeur, il suffit de\nfaire :",[235,491,493],{"className":237,"code":492,"language":239,"meta":45,"style":45},"QWeakPointer\u003CMyObject> ptrW = ptr->toWeakRef ();\n",[152,494,495],{"__ignoreMap":45},[243,496,497,499,501,503,505,508,511,513,515,518],{"class":245,"line":246},[243,498,488],{"class":249},[243,500,267],{"class":266},[243,502,270],{"class":249},[243,504,273],{"class":266},[243,506,507],{"class":249}," ptrW ",[243,509,510],{"class":266},"=",[243,512,277],{"class":322},[243,514,201],{"class":249},[243,516,517],{"class":276},"toWeakRef",[243,519,520],{"class":249}," ();\n",[17,522,523,526,527,529,530,533,534,536,537,95],{},[152,524,525],{},"ptrW"," n'incrémente donc pas le comptage de référence, cela signifie\ndonc que le pointeur peut être détruit même si un objet ",[152,528,488],{},"\nexiste. Il sera alors possible de faire un ",[152,531,532],{},"ptrW.isNull()"," pour savoir\nsi le pointeur est toujours valide. Si l'utilisateur a également besoin\nd'avoir accès à un membre de l'objet, il pourra le transformer en\n",[152,535,124],{}," avant de l'utiliser sauf si le pointeur est ",[152,538,539],{},"null",[235,541,543],{"className":237,"code":542,"language":239,"meta":45,"style":45},"QSharedPointer\u003CMyObject> ptr2 = ptrW->toStrongRef ();\nif (ptr)\n{\n    ptr->maMethodePtr();\n}\n",[152,544,545,570,577,581,593],{"__ignoreMap":45},[243,546,547,549,551,553,555,558,560,563,565,568],{"class":245,"line":246},[243,548,124],{"class":249},[243,550,267],{"class":266},[243,552,270],{"class":249},[243,554,273],{"class":266},[243,556,557],{"class":249}," ptr2 ",[243,559,510],{"class":266},[243,561,562],{"class":322}," ptrW",[243,564,201],{"class":249},[243,566,567],{"class":276},"toStrongRef",[243,569,520],{"class":249},[243,571,572,575],{"class":245,"line":253},[243,573,574],{"class":266},"if",[243,576,310],{"class":249},[243,578,579],{"class":245,"line":260},[243,580,250],{"class":249},[243,582,583,585,587,590],{"class":245,"line":291},[243,584,425],{"class":322},[243,586,201],{"class":249},[243,588,589],{"class":276},"maMethodePtr",[243,591,592],{"class":249},"();\n",[243,594,595],{"class":245,"line":298},[243,596,363],{"class":249},[17,598,599,600,603,604,606,607,609],{},"Il faut tester que ",[152,601,602],{},"ptr2"," est encore valide, car tant que la\ntransformation du pointeur ",[20,605,484],{}," vers le ",[152,608,124],{}," n'a pas\nencore été fait, il est possible que le nombre de référence vers l'objet\nsoit tombé à 0 et qu'il ait été supprimé.",[144,611,613,614],{"id":612},"comment-utiliser-this","Comment utiliser ",[152,615,474],{},[17,617,618,619,621,622,624],{},"Un des points peu pratique de l'utilisation de ",[152,620,124],{}," est que\nle comptage de référence ne fonctionne pas si plusieurs ",[152,623,124],{},"\npointent vers le même objet mais ont tous été créés à partir du pointeur\nC. Prenons par exemple, le cas suivant :",[235,626,628],{"className":237,"code":627,"language":239,"meta":45,"style":45},"MyObject * ptr = new MyObject();\n\nQSharedPointer\u003CMyObject> ptr1 = QSharedPointer(ptr);\nQSharedPointer\u003CMyObject> ptr2 = QSharedPointer(ptr);\n",[152,629,630,650,654,674],{"__ignoreMap":45},[243,631,632,635,638,641,643,646,648],{"class":245,"line":246},[243,633,634],{"class":249},"MyObject ",[243,636,637],{"class":266},"*",[243,639,640],{"class":249}," ptr ",[243,642,510],{"class":266},[243,644,645],{"class":266}," new",[243,647,285],{"class":276},[243,649,592],{"class":249},[243,651,652],{"class":245,"line":253},[243,653,295],{"emptyLinePlaceholder":294},[243,655,656,658,660,662,664,667,669,672],{"class":245,"line":260},[243,657,124],{"class":249},[243,659,267],{"class":266},[243,661,270],{"class":249},[243,663,273],{"class":266},[243,665,666],{"class":249}," ptr1 ",[243,668,510],{"class":266},[243,670,671],{"class":276}," QSharedPointer",[243,673,357],{"class":249},[243,675,676,678,680,682,684,686,688,690],{"class":245,"line":291},[243,677,124],{"class":249},[243,679,267],{"class":266},[243,681,270],{"class":249},[243,683,273],{"class":266},[243,685,557],{"class":249},[243,687,510],{"class":266},[243,689,671],{"class":276},[243,691,357],{"class":249},[17,693,694,695,698,699,701],{},"Le problème d'écrire ces lignes ainsi, et que pour ",[152,696,697],{},"ptr1"," comme pour\n",[152,700,602],{},", l'objet n'est référencé qu'une fois. Ainsi le premier qui\ntombera à 0 détruira l'objet, alors que l'autre pourrait encore\nl'utiliser. Il faut donc écrire les choses comme suite :",[17,703,704],{},[176,705],{"alt":706,"src":707},"Deux QSharedPointer créé vers la même adresse","\u002FProgrammation\u002Fqt-performance-de-l-utilisation-de-qsharedpointer\u002FQSharedPointer2.png",[235,709,711],{"className":237,"code":710,"language":239,"meta":45,"style":45},"QSharedPointer\u003CMyObject> ptr1 = QSharedPointer(new MyObject());\nQSharedPointer\u003CMyObject> ptr2 = ptr1;\n",[152,712,713,737],{"__ignoreMap":45},[243,714,715,717,719,721,723,725,727,729,731,733,735],{"class":245,"line":246},[243,716,124],{"class":249},[243,718,267],{"class":266},[243,720,270],{"class":249},[243,722,273],{"class":266},[243,724,666],{"class":249},[243,726,510],{"class":266},[243,728,671],{"class":276},[243,730,280],{"class":249},[243,732,214],{"class":266},[243,734,285],{"class":276},[243,736,288],{"class":249},[243,738,739,741,743,745,747,749,751],{"class":245,"line":253},[243,740,124],{"class":249},[243,742,267],{"class":266},[243,744,270],{"class":249},[243,746,273],{"class":266},[243,748,557],{"class":249},[243,750,510],{"class":266},[243,752,753],{"class":249}," ptr1;\n",[17,755,756,757,759,760,762,763,765,766,768,769,771,772,774,775,95],{},"Ainsi ",[152,758,697],{}," et ",[152,761,602],{}," ont bien chacun connaissance de l'existence de\nl'autre. Cela contraint donc à remplacer toutes les déclarations du type\n",[152,764,189],{}," par ",[152,767,193],{},". Ceci est donc à faire dans\nles paramètres des méthodes, dans les membres, dans la déclaration des\nvariables locales, ... . On ne peut donc plus utiliser le pointeur C\n",[152,770,189],{}," directement, mais seulement au travers de ",[152,773,124],{},"\nou de ",[152,776,488],{},[17,778,779,780,782],{},"Cela commence à poser problème lors de l'utilisation de ",[152,781,474],{}," dans un\nobjet. Imaginons une méthode d'un objet mettant à jour des membres fils\navec en paramètre le père. Nous aurions alors tendance à écrire ceci :",[235,784,786],{"className":237,"code":785,"language":239,"meta":45,"style":45},"void Object2::setParent(QSharedPointer\u003CMyObject> parent)\n{\n    ...\n}\n\n....\n\nvoid MyObject::setMember(Object2 * obj)\n{\n    _membre = obj;\n    if (obj)\n    {\n        obj->setParent(QSharedPointer\u003CMyObject>(this));\n    }\n}\n",[152,787,788,816,820,825,829,833,838,842,866,870,880,887,891,916,921],{"__ignoreMap":45},[243,789,790,792,795,798,801,803,805,807,809,811,814],{"class":245,"line":246},[243,791,396],{"class":266},[243,793,794],{"class":322}," Object2",[243,796,797],{"class":249},"::",[243,799,800],{"class":276},"setParent",[243,802,280],{"class":249},[243,804,124],{"class":322},[243,806,267],{"class":249},[243,808,270],{"class":322},[243,810,410],{"class":249},[243,812,813],{"class":413},"parent",[243,815,416],{"class":249},[243,817,818],{"class":245,"line":253},[243,819,250],{"class":249},[243,821,822],{"class":245,"line":260},[243,823,824],{"class":249},"    ...\n",[243,826,827],{"class":245,"line":291},[243,828,363],{"class":249},[243,830,831],{"class":245,"line":298},[243,832,295],{"emptyLinePlaceholder":294},[243,834,835],{"class":245,"line":304},[243,836,837],{"class":249},"....\n",[243,839,840],{"class":245,"line":313},[243,841,295],{"emptyLinePlaceholder":294},[243,843,844,846,848,850,853,855,858,861,864],{"class":245,"line":319},[243,845,396],{"class":266},[243,847,285],{"class":322},[243,849,797],{"class":249},[243,851,852],{"class":276},"setMember",[243,854,280],{"class":249},[243,856,857],{"class":322},"Object2",[243,859,860],{"class":266}," *",[243,862,863],{"class":413}," obj",[243,865,416],{"class":249},[243,867,868],{"class":245,"line":334},[243,869,250],{"class":249},[243,871,872,875,877],{"class":245,"line":340},[243,873,874],{"class":249},"    _membre ",[243,876,510],{"class":266},[243,878,879],{"class":249}," obj;\n",[243,881,882,884],{"class":245,"line":345},[243,883,307],{"class":266},[243,885,886],{"class":249}," (obj)\n",[243,888,889],{"class":245,"line":351},[243,890,316],{"class":249},[243,892,893,896,898,900,902,904,906,908,911,913],{"class":245,"line":360},[243,894,895],{"class":322},"        obj",[243,897,201],{"class":249},[243,899,800],{"class":276},[243,901,280],{"class":249},[243,903,124],{"class":276},[243,905,267],{"class":249},[243,907,270],{"class":322},[243,909,910],{"class":249},">(",[243,912,474],{"class":322},[243,914,915],{"class":249},"));\n",[243,917,919],{"class":245,"line":918},14,[243,920,337],{"class":249},[243,922,924],{"class":245,"line":923},15,[243,925,363],{"class":249},[17,927,928,929,931,932,940,941,943,944,95],{},"Ceci ne marchera pas car on créerait un nouvel objet ",[152,930,124],{},"\ncommençant son comptage de référence à 1, alors que nous en avons déjà\nau moins un autre pointant vers notre instance",[37,933,934],{},[40,935,939],{"href":936,"ariaDescribedBy":937,"dataFootnoteRef":45,"id":938},"#user-content-fn-5",[44],"user-content-fnref-5","5",". ",[152,942,270],{},"\npourrait alors être détruit alors qu'il est encore utilisé par\n",[152,945,857],{},[17,947,948,949,951,953],{},"Pour éviter cela, il faut alors passer par un pointeur ",[20,950,35],{},[152,952,474],{},". Pour cela nous allons utiliser deux choses :",[65,955,956,968],{},[68,957,958,959,962,963,965,967],{},"Un membre nommé ",[152,960,961],{},"_this"," de type pointeur ",[20,964,35],{},[152,966,488],{},", contenant une référence à l'objet lui même. (Nous\nn'utilisons pas un QSharedPointer, pour éviter une référence\ncirculaire, voir le paragraphe suivant).",[68,969,970],{},"Une méthode statique utilisée pour la création (nous n'allons plus\nutiliser le constructeur, car à ce moment, il n'existe pas encore de\nQSharedPointer pointant vers notre objet).",[17,972,973],{},"Voici un exemple de comment écrire le constructeur maison :",[235,975,977],{"className":237,"code":976,"language":239,"meta":45,"style":45},"class MyObject\n{\npublic:\n    static QSharedPointer\u003CMyObject> create(QString parametre)\n    {\n        QSharedPointer\u003CMyObject> ptr(new MyObject(parametre);\n        ptr->_this = ptr.toWeakRef();\n        return ptr;\n    }\nprivate:\n    MyObject(QString parametre)\n    {\n        ...\n    }\n\n    QWeakPointer\u003CMyObject> _this;\n};\n",[152,978,979,987,991,996,1021,1025,1047,1065,1072,1076,1081,1089,1093,1098,1102,1106,1121],{"__ignoreMap":45},[243,980,981,984],{"class":245,"line":246},[243,982,983],{"class":266},"class",[243,985,986],{"class":322}," MyObject\n",[243,988,989],{"class":245,"line":253},[243,990,250],{"class":249},[243,992,993],{"class":245,"line":260},[243,994,995],{"class":266},"public:\n",[243,997,998,1001,1003,1005,1007,1009,1012,1014,1016,1019],{"class":245,"line":291},[243,999,1000],{"class":266},"    static",[243,1002,671],{"class":322},[243,1004,267],{"class":249},[243,1006,270],{"class":322},[243,1008,410],{"class":249},[243,1010,1011],{"class":276},"create",[243,1013,280],{"class":249},[243,1015,85],{"class":322},[243,1017,1018],{"class":413}," parametre",[243,1020,416],{"class":249},[243,1022,1023],{"class":245,"line":298},[243,1024,316],{"class":249},[243,1026,1027,1030,1032,1034,1036,1038,1040,1042,1044],{"class":245,"line":304},[243,1028,1029],{"class":249},"        QSharedPointer",[243,1031,267],{"class":266},[243,1033,270],{"class":249},[243,1035,273],{"class":266},[243,1037,277],{"class":276},[243,1039,280],{"class":249},[243,1041,214],{"class":266},[243,1043,285],{"class":276},[243,1045,1046],{"class":249},"(parametre);\n",[243,1048,1049,1051,1053,1055,1057,1059,1061,1063],{"class":245,"line":313},[243,1050,323],{"class":322},[243,1052,201],{"class":249},[243,1054,961],{"class":453},[243,1056,457],{"class":266},[243,1058,277],{"class":322},[243,1060,95],{"class":249},[243,1062,517],{"class":276},[243,1064,592],{"class":249},[243,1066,1067,1070],{"class":245,"line":319},[243,1068,1069],{"class":266},"        return",[243,1071,460],{"class":249},[243,1073,1074],{"class":245,"line":334},[243,1075,337],{"class":249},[243,1077,1078],{"class":245,"line":340},[243,1079,1080],{"class":249},"private:\n",[243,1082,1083,1086],{"class":245,"line":345},[243,1084,1085],{"class":276},"    MyObject",[243,1087,1088],{"class":249},"(QString parametre)\n",[243,1090,1091],{"class":245,"line":351},[243,1092,316],{"class":249},[243,1094,1095],{"class":245,"line":360},[243,1096,1097],{"class":249},"        ...\n",[243,1099,1100],{"class":245,"line":918},[243,1101,337],{"class":249},[243,1103,1104],{"class":245,"line":923},[243,1105,295],{"emptyLinePlaceholder":294},[243,1107,1109,1112,1114,1116,1118],{"class":245,"line":1108},16,[243,1110,1111],{"class":249},"    QWeakPointer",[243,1113,267],{"class":266},[243,1115,270],{"class":249},[243,1117,273],{"class":266},[243,1119,1120],{"class":249}," _this;\n",[243,1122,1124],{"class":245,"line":1123},17,[243,1125,1126],{"class":249},"};\n",[17,1128,1129,1130,1132,1133,1135,1136,1138,1139,1141,1142,1144,1145,1147,1148,95],{},"Le constructeur devient alors privé (ou protégé si on a besoin de la\nnotion d'héritage) afin d'obliger l'utilisateur de la classe à utiliser\nnotre méthode de création. Dans notre nouvelle méthode de création\n",[152,1131,1011],{},", qui est une méthode statique, nous allons créer le pointeur et\ninitialiser le ",[152,1134,488],{}," de notre objet avec le pointeur\n",[20,1137,35],{}," que nous venons de créer. Nous retournons un\n",[152,1140,124],{},". La méthode ",[152,1143,1011],{}," devient alors notre nouveau\nconstructeur, mais créant des instances d'objets de type\n",[152,1146,193],{}," et non plus des instances d'objet\n",[152,1149,189],{},[17,1151,1152,1153,1156],{},"Notre méthode ",[152,1154,1155],{},"setMember()"," peut alors être ré-écrite :",[235,1158,1160],{"className":237,"code":1159,"language":239,"meta":45,"style":45},"void MyObject::setMember(Object2 * obj)\n{\n    _membre = obj;\n    if (obj)\n    {\n        obj->setParent(_this.toStrongRef());\n    }\n}\n",[152,1161,1162,1182,1186,1194,1200,1204,1222,1226],{"__ignoreMap":45},[243,1163,1164,1166,1168,1170,1172,1174,1176,1178,1180],{"class":245,"line":246},[243,1165,396],{"class":266},[243,1167,285],{"class":322},[243,1169,797],{"class":249},[243,1171,852],{"class":276},[243,1173,280],{"class":249},[243,1175,857],{"class":322},[243,1177,860],{"class":266},[243,1179,863],{"class":413},[243,1181,416],{"class":249},[243,1183,1184],{"class":245,"line":253},[243,1185,250],{"class":249},[243,1187,1188,1190,1192],{"class":245,"line":260},[243,1189,874],{"class":249},[243,1191,510],{"class":266},[243,1193,879],{"class":249},[243,1195,1196,1198],{"class":245,"line":291},[243,1197,307],{"class":266},[243,1199,886],{"class":249},[243,1201,1202],{"class":245,"line":298},[243,1203,316],{"class":249},[243,1205,1206,1208,1210,1212,1214,1216,1218,1220],{"class":245,"line":304},[243,1207,895],{"class":322},[243,1209,201],{"class":249},[243,1211,800],{"class":276},[243,1213,280],{"class":249},[243,1215,961],{"class":322},[243,1217,95],{"class":249},[243,1219,567],{"class":276},[243,1221,288],{"class":249},[243,1223,1224],{"class":245,"line":313},[243,1225,337],{"class":249},[243,1227,1228],{"class":245,"line":319},[243,1229,363],{"class":249},[144,1231,1233],{"id":1232},"comment-éviter-les-références-circulaires","Comment éviter les références circulaires",[17,1235,1236],{},"Le principe d'une référence circulaire est qu'un objet A référence\nl'objet B et l'objet B référence l'objet A.",[17,1238,1239],{},"Voici par exemple, un cas de référence circulaire :",[235,1241,1243],{"className":237,"code":1242,"language":239,"meta":45,"style":45},"class A\n{\npublic:\n    static create()\n    {\n        QSharedPointer\u003CA> ptr(new A());\n        return ptr;\n    }\n    ~A()\n    {\n    }\nprivate:\n    A()\n    {\n        b = B::create();\n        b->setA(_this);\n    }\n    QSharedPointer\u003CB> b;\n    QWeakPointer\u003CA> _this;\n};\n\nclass B\n{\npublic:\n    static QSharedPointer\u003CB> create()\n    {\n        QSharedPointer\u003CB> ptr(new B());\n        return ptr;\n    }\n    void setA(QSharedPointer\u003CA> b);\n    QSharedPointer\u003CA> getA();\nprivate:\n    QSharedPointer\u003CA>  a;\n};\n",[152,1244,1245,1252,1256,1260,1270,1274,1296,1302,1306,1313,1317,1321,1325,1332,1336,1350,1363,1367,1382,1395,1400,1405,1413,1418,1423,1440,1445,1467,1474,1479,1504,1520,1525,1539],{"__ignoreMap":45},[243,1246,1247,1249],{"class":245,"line":246},[243,1248,983],{"class":266},[243,1250,1251],{"class":322}," A\n",[243,1253,1254],{"class":245,"line":253},[243,1255,250],{"class":249},[243,1257,1258],{"class":245,"line":260},[243,1259,995],{"class":266},[243,1261,1262,1264,1267],{"class":245,"line":291},[243,1263,1000],{"class":266},[243,1265,1266],{"class":276}," create",[243,1268,1269],{"class":249},"()\n",[243,1271,1272],{"class":245,"line":298},[243,1273,316],{"class":249},[243,1275,1276,1278,1280,1283,1285,1287,1289,1291,1294],{"class":245,"line":304},[243,1277,1029],{"class":249},[243,1279,267],{"class":266},[243,1281,1282],{"class":249},"A",[243,1284,273],{"class":266},[243,1286,277],{"class":276},[243,1288,280],{"class":249},[243,1290,214],{"class":266},[243,1292,1293],{"class":276}," A",[243,1295,288],{"class":249},[243,1297,1298,1300],{"class":245,"line":313},[243,1299,1069],{"class":266},[243,1301,460],{"class":249},[243,1303,1304],{"class":245,"line":319},[243,1305,337],{"class":249},[243,1307,1308,1311],{"class":245,"line":334},[243,1309,1310],{"class":276},"    ~A",[243,1312,1269],{"class":249},[243,1314,1315],{"class":245,"line":340},[243,1316,316],{"class":249},[243,1318,1319],{"class":245,"line":345},[243,1320,337],{"class":249},[243,1322,1323],{"class":245,"line":351},[243,1324,1080],{"class":266},[243,1326,1327,1330],{"class":245,"line":360},[243,1328,1329],{"class":276},"    A",[243,1331,1269],{"class":249},[243,1333,1334],{"class":245,"line":918},[243,1335,316],{"class":249},[243,1337,1338,1341,1343,1346,1348],{"class":245,"line":923},[243,1339,1340],{"class":249},"        b ",[243,1342,510],{"class":266},[243,1344,1345],{"class":249}," B::",[243,1347,1011],{"class":276},[243,1349,592],{"class":249},[243,1351,1352,1355,1357,1360],{"class":245,"line":1108},[243,1353,1354],{"class":322},"        b",[243,1356,201],{"class":249},[243,1358,1359],{"class":276},"setA",[243,1361,1362],{"class":249},"(_this);\n",[243,1364,1365],{"class":245,"line":1123},[243,1366,337],{"class":249},[243,1368,1370,1372,1374,1377,1379],{"class":245,"line":1369},18,[243,1371,263],{"class":249},[243,1373,267],{"class":266},[243,1375,1376],{"class":249},"B",[243,1378,273],{"class":266},[243,1380,1381],{"class":249}," b;\n",[243,1383,1385,1387,1389,1391,1393],{"class":245,"line":1384},19,[243,1386,1111],{"class":249},[243,1388,267],{"class":266},[243,1390,1282],{"class":249},[243,1392,273],{"class":266},[243,1394,1120],{"class":249},[243,1396,1398],{"class":245,"line":1397},20,[243,1399,1126],{"class":249},[243,1401,1403],{"class":245,"line":1402},21,[243,1404,295],{"emptyLinePlaceholder":294},[243,1406,1408,1410],{"class":245,"line":1407},22,[243,1409,983],{"class":266},[243,1411,1412],{"class":322}," B\n",[243,1414,1416],{"class":245,"line":1415},23,[243,1417,250],{"class":249},[243,1419,1421],{"class":245,"line":1420},24,[243,1422,995],{"class":266},[243,1424,1426,1428,1430,1432,1434,1436,1438],{"class":245,"line":1425},25,[243,1427,1000],{"class":266},[243,1429,671],{"class":322},[243,1431,267],{"class":249},[243,1433,1376],{"class":322},[243,1435,410],{"class":249},[243,1437,1011],{"class":276},[243,1439,1269],{"class":249},[243,1441,1443],{"class":245,"line":1442},26,[243,1444,316],{"class":249},[243,1446,1448,1450,1452,1454,1456,1458,1460,1462,1465],{"class":245,"line":1447},27,[243,1449,1029],{"class":249},[243,1451,267],{"class":266},[243,1453,1376],{"class":249},[243,1455,273],{"class":266},[243,1457,277],{"class":276},[243,1459,280],{"class":249},[243,1461,214],{"class":266},[243,1463,1464],{"class":276}," B",[243,1466,288],{"class":249},[243,1468,1470,1472],{"class":245,"line":1469},28,[243,1471,1069],{"class":266},[243,1473,460],{"class":249},[243,1475,1477],{"class":245,"line":1476},29,[243,1478,337],{"class":249},[243,1480,1482,1485,1488,1490,1492,1494,1496,1498,1501],{"class":245,"line":1481},30,[243,1483,1484],{"class":266},"    void",[243,1486,1487],{"class":276}," setA",[243,1489,280],{"class":249},[243,1491,124],{"class":322},[243,1493,267],{"class":249},[243,1495,1282],{"class":322},[243,1497,410],{"class":249},[243,1499,1500],{"class":413},"b",[243,1502,1503],{"class":249},");\n",[243,1505,1507,1509,1511,1513,1515,1518],{"class":245,"line":1506},31,[243,1508,263],{"class":322},[243,1510,267],{"class":249},[243,1512,1282],{"class":322},[243,1514,410],{"class":249},[243,1516,1517],{"class":276},"getA",[243,1519,592],{"class":249},[243,1521,1523],{"class":245,"line":1522},32,[243,1524,1080],{"class":266},[243,1526,1528,1530,1532,1534,1536],{"class":245,"line":1527},33,[243,1529,263],{"class":249},[243,1531,267],{"class":266},[243,1533,1282],{"class":249},[243,1535,273],{"class":266},[243,1537,1538],{"class":249},"  a;\n",[243,1540,1542],{"class":245,"line":1541},34,[243,1543,1126],{"class":249},[17,1545,1546],{},"Cela peut-être aussi le cas, si par exemple une instance d'objet C\nréférence des instances d'objets fils C, qui possèdent eux-même un\npointeur vers l'objet C père.",[235,1548,1550],{"className":237,"code":1549,"language":239,"meta":45,"style":45},"class C\n{\npublic:\n    static QSharedPointer\u003CC> create()\n    {\n        QSharedPointer\u003CC> ptr(new C());\n        _this = ptr.toWeakPtr();\n        return ptr;\n    }\n\n    ~C()\n    {\n    }\n\n    void addChild(QSharedPointer\u003CC> c)\n    {\n        _childs.append(c);\n        c->setParent(_this);\n    }\n\n    void setParent(QSharedPointer\u003CC> c);\n    QSharedPointer\u003CC> getParent();\nprivate:\n    C()\n    {\n    }\n\n    QWeakPointer\u003CC> _this;\n    QSharedPointer\u003CC> _parent;\n    QList\u003C QSharedPointer\u003CC> > _childs;\n};\n",[152,1551,1552,1559,1563,1567,1584,1588,1609,1625,1631,1635,1639,1646,1650,1654,1658,1680,1684,1697,1708,1712,1716,1737,1752,1756,1763,1767,1771,1775,1787,1800,1821],{"__ignoreMap":45},[243,1553,1554,1556],{"class":245,"line":246},[243,1555,983],{"class":266},[243,1557,1558],{"class":322}," C\n",[243,1560,1561],{"class":245,"line":253},[243,1562,250],{"class":249},[243,1564,1565],{"class":245,"line":260},[243,1566,995],{"class":266},[243,1568,1569,1571,1573,1575,1578,1580,1582],{"class":245,"line":291},[243,1570,1000],{"class":266},[243,1572,671],{"class":322},[243,1574,267],{"class":249},[243,1576,1577],{"class":322},"C",[243,1579,410],{"class":249},[243,1581,1011],{"class":276},[243,1583,1269],{"class":249},[243,1585,1586],{"class":245,"line":298},[243,1587,316],{"class":249},[243,1589,1590,1592,1594,1596,1598,1600,1602,1604,1607],{"class":245,"line":304},[243,1591,1029],{"class":249},[243,1593,267],{"class":266},[243,1595,1577],{"class":249},[243,1597,273],{"class":266},[243,1599,277],{"class":276},[243,1601,280],{"class":249},[243,1603,214],{"class":266},[243,1605,1606],{"class":276}," C",[243,1608,288],{"class":249},[243,1610,1611,1614,1616,1618,1620,1623],{"class":245,"line":313},[243,1612,1613],{"class":249},"        _this ",[243,1615,510],{"class":266},[243,1617,277],{"class":322},[243,1619,95],{"class":249},[243,1621,1622],{"class":276},"toWeakPtr",[243,1624,592],{"class":249},[243,1626,1627,1629],{"class":245,"line":319},[243,1628,1069],{"class":266},[243,1630,460],{"class":249},[243,1632,1633],{"class":245,"line":334},[243,1634,337],{"class":249},[243,1636,1637],{"class":245,"line":340},[243,1638,295],{"emptyLinePlaceholder":294},[243,1640,1641,1644],{"class":245,"line":345},[243,1642,1643],{"class":276},"    ~C",[243,1645,1269],{"class":249},[243,1647,1648],{"class":245,"line":351},[243,1649,316],{"class":249},[243,1651,1652],{"class":245,"line":360},[243,1653,337],{"class":249},[243,1655,1656],{"class":245,"line":918},[243,1657,295],{"emptyLinePlaceholder":294},[243,1659,1660,1662,1665,1667,1669,1671,1673,1675,1678],{"class":245,"line":923},[243,1661,1484],{"class":266},[243,1663,1664],{"class":276}," addChild",[243,1666,280],{"class":249},[243,1668,124],{"class":322},[243,1670,267],{"class":249},[243,1672,1577],{"class":322},[243,1674,410],{"class":249},[243,1676,1677],{"class":413},"c",[243,1679,416],{"class":249},[243,1681,1682],{"class":245,"line":1108},[243,1683,316],{"class":249},[243,1685,1686,1689,1691,1694],{"class":245,"line":1123},[243,1687,1688],{"class":322},"        _childs",[243,1690,95],{"class":249},[243,1692,1693],{"class":276},"append",[243,1695,1696],{"class":249},"(c);\n",[243,1698,1699,1702,1704,1706],{"class":245,"line":1369},[243,1700,1701],{"class":322},"        c",[243,1703,201],{"class":249},[243,1705,800],{"class":276},[243,1707,1362],{"class":249},[243,1709,1710],{"class":245,"line":1384},[243,1711,337],{"class":249},[243,1713,1714],{"class":245,"line":1397},[243,1715,295],{"emptyLinePlaceholder":294},[243,1717,1718,1720,1723,1725,1727,1729,1731,1733,1735],{"class":245,"line":1402},[243,1719,1484],{"class":266},[243,1721,1722],{"class":276}," setParent",[243,1724,280],{"class":249},[243,1726,124],{"class":322},[243,1728,267],{"class":249},[243,1730,1577],{"class":322},[243,1732,410],{"class":249},[243,1734,1677],{"class":413},[243,1736,1503],{"class":249},[243,1738,1739,1741,1743,1745,1747,1750],{"class":245,"line":1407},[243,1740,263],{"class":322},[243,1742,267],{"class":249},[243,1744,1577],{"class":322},[243,1746,410],{"class":249},[243,1748,1749],{"class":276},"getParent",[243,1751,592],{"class":249},[243,1753,1754],{"class":245,"line":1415},[243,1755,1080],{"class":266},[243,1757,1758,1761],{"class":245,"line":1420},[243,1759,1760],{"class":276},"    C",[243,1762,1269],{"class":249},[243,1764,1765],{"class":245,"line":1425},[243,1766,316],{"class":249},[243,1768,1769],{"class":245,"line":1442},[243,1770,337],{"class":249},[243,1772,1773],{"class":245,"line":1447},[243,1774,295],{"emptyLinePlaceholder":294},[243,1776,1777,1779,1781,1783,1785],{"class":245,"line":1469},[243,1778,1111],{"class":249},[243,1780,267],{"class":266},[243,1782,1577],{"class":249},[243,1784,273],{"class":266},[243,1786,1120],{"class":249},[243,1788,1789,1791,1793,1795,1797],{"class":245,"line":1476},[243,1790,263],{"class":249},[243,1792,267],{"class":266},[243,1794,1577],{"class":249},[243,1796,273],{"class":266},[243,1798,1799],{"class":249}," _parent;\n",[243,1801,1802,1805,1807,1809,1811,1813,1815,1818],{"class":245,"line":1481},[243,1803,1804],{"class":249},"    QList",[243,1806,267],{"class":266},[243,1808,671],{"class":249},[243,1810,267],{"class":266},[243,1812,1577],{"class":249},[243,1814,273],{"class":266},[243,1816,1817],{"class":266}," >",[243,1819,1820],{"class":249}," _childs;\n",[243,1822,1823],{"class":245,"line":1506},[243,1824,1126],{"class":249},[17,1826,1827],{},"Dans ces cas là, on a :- L'objet A possède la référence vers l'objet B-\nL'objet B possède une référence vers l'objet A.- Même principe avec\nl'objet C",[17,1829,1830],{},[176,1831],{"alt":1832,"src":1833},"Reference circulaire de QSharedPointer","\u002FProgrammation\u002Fqt-performance-de-l-utilisation-de-qsharedpointer\u002FQSharedPointer3.png",[17,1835,1836],{},"Dans ce cas, il restera alors toujours une référence vers A, et une vers\nB, même si plus aucune variable ne référence ces objets. Cette référence\ncirculaire fait que l'objet ne sera jamais détruit même si on n'a plus\nbesoin de l'objet.",[17,1838,1839],{},"Si on décide que l'objet A sera l'objet maitre (donc que sa destruction\nengendrera la destruction de l'objet B), on peut alors écrire les choses\nainsi pour l'objet B :",[235,1841,1843],{"className":237,"code":1842,"language":239,"meta":45,"style":45},"class B\n{\npublic:\n    static QSharedPointer\u003CB> create()\n    {\n        QSharedPointer\u003CB> ptr(new B());\n        return ptr;\n    }\n    void setA(QWeakPointer\u003CA> b);\n    QWeakPointer\u003CA> getA();\nprivate:\n    QWeakPointer\u003CA>  a;\n};\n",[152,1844,1845,1851,1855,1859,1875,1879,1899,1905,1909,1929,1943,1947,1959],{"__ignoreMap":45},[243,1846,1847,1849],{"class":245,"line":246},[243,1848,983],{"class":266},[243,1850,1412],{"class":322},[243,1852,1853],{"class":245,"line":253},[243,1854,250],{"class":249},[243,1856,1857],{"class":245,"line":260},[243,1858,995],{"class":266},[243,1860,1861,1863,1865,1867,1869,1871,1873],{"class":245,"line":291},[243,1862,1000],{"class":266},[243,1864,671],{"class":322},[243,1866,267],{"class":249},[243,1868,1376],{"class":322},[243,1870,410],{"class":249},[243,1872,1011],{"class":276},[243,1874,1269],{"class":249},[243,1876,1877],{"class":245,"line":298},[243,1878,316],{"class":249},[243,1880,1881,1883,1885,1887,1889,1891,1893,1895,1897],{"class":245,"line":304},[243,1882,1029],{"class":249},[243,1884,267],{"class":266},[243,1886,1376],{"class":249},[243,1888,273],{"class":266},[243,1890,277],{"class":276},[243,1892,280],{"class":249},[243,1894,214],{"class":266},[243,1896,1464],{"class":276},[243,1898,288],{"class":249},[243,1900,1901,1903],{"class":245,"line":313},[243,1902,1069],{"class":266},[243,1904,460],{"class":249},[243,1906,1907],{"class":245,"line":319},[243,1908,337],{"class":249},[243,1910,1911,1913,1915,1917,1919,1921,1923,1925,1927],{"class":245,"line":334},[243,1912,1484],{"class":266},[243,1914,1487],{"class":276},[243,1916,280],{"class":249},[243,1918,488],{"class":322},[243,1920,267],{"class":249},[243,1922,1282],{"class":322},[243,1924,410],{"class":249},[243,1926,1500],{"class":413},[243,1928,1503],{"class":249},[243,1930,1931,1933,1935,1937,1939,1941],{"class":245,"line":340},[243,1932,1111],{"class":322},[243,1934,267],{"class":249},[243,1936,1282],{"class":322},[243,1938,410],{"class":249},[243,1940,1517],{"class":276},[243,1942,592],{"class":249},[243,1944,1945],{"class":245,"line":345},[243,1946,1080],{"class":266},[243,1948,1949,1951,1953,1955,1957],{"class":245,"line":351},[243,1950,1111],{"class":249},[243,1952,267],{"class":266},[243,1954,1282],{"class":249},[243,1956,273],{"class":266},[243,1958,1538],{"class":249},[243,1960,1961],{"class":245,"line":360},[243,1962,1126],{"class":249},[17,1964,1965,1966,1968,1969,1971,1972,1974,1975,1983,1984,95],{},"Dans ce cas, avec l'utilisation d'un ",[152,1967,488],{},", lorsque qu'il\nn'existera plus de référence vers l'objet A, le pointeur ",[20,1970,484],{}," ",[152,1973,40],{},"\nsera mis à jour comme ne contenant plus de référence",[37,1976,1977],{},[40,1978,1982],{"href":1979,"ariaDescribedBy":1980,"dataFootnoteRef":45,"id":1981},"#user-content-fn-6",[44],"user-content-fnref-6","6",".\nL'instance de l'objet A sera réellement détruite. Il n'y aura alors plus\naucune référence vers l'objet B qui sera alors également\ndétruit",[37,1985,1986],{},[40,1987,1991],{"href":1988,"ariaDescribedBy":1989,"dataFootnoteRef":45,"id":1990},"#user-content-fn-7",[44],"user-content-fnref-7","7",[144,1993,1995],{"id":1994},"utilisation-dans-les-applications-multi-thread","Utilisation dans les applications multi-thread",[17,1997,1998,1999,2001,2002,759,2004,2006],{},"L'utilisation de ",[152,2000,124],{}," simplifie l'écriture des applications\nmulti-thread (les objets ",[152,2003,124],{},[152,2005,488],{}," sont\nthread-safe).",[17,2008,2009,2010,2018,2019,95],{},"Dans ces applications il n'y a alors plus besoin de se soucier si\nl'objet est en cours d'utilisation ailleurs dans l'application avant de\nle supprimer",[37,2011,2012],{},[40,2013,2017],{"href":2014,"ariaDescribedBy":2015,"dataFootnoteRef":45,"id":2016},"#user-content-fn-8",[44],"user-content-fnref-8","8",". Lorsqu'un pointeur ne devient plus utilisé dans\nun thread donné, il ne sera détruit que s'il n'y a pas d'autres\nréférences dans d'autres threads de l'application",[37,2020,2021],{},[40,2022,2026],{"href":2023,"ariaDescribedBy":2024,"dataFootnoteRef":45,"id":2025},"#user-content-fn-9",[44],"user-content-fnref-9","9",[17,2028,2029,2030,2032,2033,95],{},"Avec l'utilisation de ",[152,2031,488],{},", un thread pourra tester\nl'existence du pointeur avant d'effectuer une opération et pourra aviser\nle cas échéant sans faire planter toute l'application",[37,2034,2035],{},[40,2036,2040],{"href":2037,"ariaDescribedBy":2038,"dataFootnoteRef":45,"id":2039},"#user-content-fn-10",[44],"user-content-fnref-10","10",[144,2042,2044],{"id":2043},"utilisation-dun-pool","Utilisation d'un pool",[17,2046,2047,2048,2053],{},"Si la création et la destruction d'un objet est coûteux, il est\nenvisageable de diminuer le coût de destruction et de création d'un\nthread en utilisant un Pool d'objet. Dans ce cas l'objet ",[40,2049,2052],{"href":2050,"rel":2051},"http:\u002F\u002Fdoc.qt.nokia.com\u002F4.6\u002Fqqueue.html",[74],"QQueue","\npourra être utilisé pour représenter notre Pool.",[17,2055,2056,2057,2059,2060,95],{},"Lors de la demande de création, en utilisant notre méthode ",[152,2058,1011],{},"\nci-dessus, on prend alors une valeur du pool (si disponible) et on la\nretourne sous forme d'un ",[152,2061,124],{},[235,2063,2065],{"className":237,"code":2064,"language":239,"meta":45,"style":45},"QSharedPointer\u003CMyObject> MyObject::create()\n{\n    MyObject * c_ptr;\n    if (_queue.size())\n    {\n    c_ptr = _queue.dequeue();\n    }\n    else\n    {\n    c_ptr = new MyObject();\n    }\n    QSharedPointer\u003CMyObject> ptr(c_ptr, ReturnToPool);\n    ptr->_this = ptr.toWeakRef();\n    return ptr;\n}\n",[152,2066,2067,2085,2089,2099,2117,2121,2138,2142,2147,2151,2163,2167,2182,2200,2207],{"__ignoreMap":45},[243,2068,2069,2071,2073,2075,2077,2079,2081,2083],{"class":245,"line":246},[243,2070,124],{"class":322},[243,2072,267],{"class":249},[243,2074,270],{"class":322},[243,2076,410],{"class":249},[243,2078,270],{"class":322},[243,2080,797],{"class":249},[243,2082,1011],{"class":276},[243,2084,1269],{"class":249},[243,2086,2087],{"class":245,"line":253},[243,2088,250],{"class":249},[243,2090,2091,2094,2096],{"class":245,"line":260},[243,2092,2093],{"class":249},"    MyObject ",[243,2095,637],{"class":266},[243,2097,2098],{"class":249}," c_ptr;\n",[243,2100,2101,2103,2106,2109,2111,2114],{"class":245,"line":291},[243,2102,307],{"class":266},[243,2104,2105],{"class":249}," (",[243,2107,2108],{"class":322},"_queue",[243,2110,95],{"class":249},[243,2112,2113],{"class":276},"size",[243,2115,2116],{"class":249},"())\n",[243,2118,2119],{"class":245,"line":298},[243,2120,316],{"class":249},[243,2122,2123,2126,2128,2131,2133,2136],{"class":245,"line":304},[243,2124,2125],{"class":249},"    c_ptr ",[243,2127,510],{"class":266},[243,2129,2130],{"class":322}," _queue",[243,2132,95],{"class":249},[243,2134,2135],{"class":276},"dequeue",[243,2137,592],{"class":249},[243,2139,2140],{"class":245,"line":313},[243,2141,337],{"class":249},[243,2143,2144],{"class":245,"line":319},[243,2145,2146],{"class":266},"    else\n",[243,2148,2149],{"class":245,"line":334},[243,2150,316],{"class":249},[243,2152,2153,2155,2157,2159,2161],{"class":245,"line":340},[243,2154,2125],{"class":249},[243,2156,510],{"class":266},[243,2158,645],{"class":266},[243,2160,285],{"class":276},[243,2162,592],{"class":249},[243,2164,2165],{"class":245,"line":345},[243,2166,337],{"class":249},[243,2168,2169,2171,2173,2175,2177,2179],{"class":245,"line":351},[243,2170,263],{"class":249},[243,2172,267],{"class":266},[243,2174,270],{"class":249},[243,2176,273],{"class":266},[243,2178,277],{"class":276},[243,2180,2181],{"class":249},"(c_ptr, ReturnToPool);\n",[243,2183,2184,2186,2188,2190,2192,2194,2196,2198],{"class":245,"line":360},[243,2185,425],{"class":322},[243,2187,201],{"class":249},[243,2189,961],{"class":453},[243,2191,457],{"class":266},[243,2193,277],{"class":322},[243,2195,95],{"class":249},[243,2197,517],{"class":276},[243,2199,592],{"class":249},[243,2201,2202,2205],{"class":245,"line":918},[243,2203,2204],{"class":266},"    return",[243,2206,460],{"class":249},[243,2208,2209],{"class":245,"line":923},[243,2210,363],{"class":249},[17,2212,2213,2214,2222,2223,2225],{},"Dans l'exemple ci-dessus",[37,2215,2216],{},[40,2217,2221],{"href":2218,"ariaDescribedBy":2219,"dataFootnoteRef":45,"id":2220},"#user-content-fn-11",[44],"user-content-fnref-11","11",", on demande à la queue, qui doit\nêtre une variable globale ou statique, un élément, et si ce n'est pas\npossible, on crée un nouvel objet de type ",[152,2224,270],{}," (dont on suppose la\ncréation coûteuse).",[17,2227,2228,2229,2231,2232,2235,2236,2239,2240,2243],{},"Lors de la création du ",[152,2230,124],{}," on utilise alors le constructeur\n",[152,2233,2234],{},"QSharedPointer ( T * ptr, Deleter deleter )"," sur lequel on définit une\nméthode ",[152,2237,2238],{},"Deleter"," nommée ",[152,2241,2242],{},"ReturnToPool"," dont le but est de remettre les\nobjets en pool.",[235,2245,2247],{"className":237,"code":2246,"language":239,"meta":45,"style":45},"static void ReturnToPool(MyObject *obj)\n{\n    if (_queue.size() \u003C MAX_SIZE_QUEUE)\n    {\n        _queue.enqueue(obj);\n    }\n    else\n    {\n        delete obj;\n    }\n}\n",[152,2248,2249,2271,2275,2295,2299,2312,2316,2320,2324,2331,2335],{"__ignoreMap":45},[243,2250,2251,2254,2257,2260,2262,2264,2266,2269],{"class":245,"line":246},[243,2252,2253],{"class":266},"static",[243,2255,2256],{"class":266}," void",[243,2258,2259],{"class":276}," ReturnToPool",[243,2261,280],{"class":249},[243,2263,270],{"class":322},[243,2265,860],{"class":266},[243,2267,2268],{"class":413},"obj",[243,2270,416],{"class":249},[243,2272,2273],{"class":245,"line":253},[243,2274,250],{"class":249},[243,2276,2277,2279,2281,2283,2285,2287,2290,2292],{"class":245,"line":260},[243,2278,307],{"class":266},[243,2280,2105],{"class":249},[243,2282,2108],{"class":322},[243,2284,95],{"class":249},[243,2286,2113],{"class":276},[243,2288,2289],{"class":249},"() ",[243,2291,267],{"class":266},[243,2293,2294],{"class":249}," MAX_SIZE_QUEUE)\n",[243,2296,2297],{"class":245,"line":291},[243,2298,316],{"class":249},[243,2300,2301,2304,2306,2309],{"class":245,"line":298},[243,2302,2303],{"class":322},"        _queue",[243,2305,95],{"class":249},[243,2307,2308],{"class":276},"enqueue",[243,2310,2311],{"class":249},"(obj);\n",[243,2313,2314],{"class":245,"line":304},[243,2315,337],{"class":249},[243,2317,2318],{"class":245,"line":313},[243,2319,2146],{"class":266},[243,2321,2322],{"class":245,"line":319},[243,2323,316],{"class":249},[243,2325,2326,2329],{"class":245,"line":334},[243,2327,2328],{"class":266},"        delete",[243,2330,879],{"class":249},[243,2332,2333],{"class":245,"line":340},[243,2334,337],{"class":249},[243,2336,2337],{"class":245,"line":345},[243,2338,363],{"class":249},[17,2340,2341],{},"Dans ce cas de retour au pool, si le pool est rempli, on détruit l'objet\n(pour éviter de consommer trop de mémoire), sinon on l'ajoute au pool.\nDans ce cas, le pool est agrandi au fur et à mesure des besoins, jusqu'à\nune taille limite.",[17,2343,2344],{},"Bien sûr il faut que la performance de l'utilisation d'un pool soit plus\nintéressante que celle de la création de l'objet et de son\ninitialisation.",[17,2346,2347],{},[2348,2349,2350,2354,2355,2357,2358,2361,2362,2364,2365,2367,2368,2370,2371,2373,2374],"strong",{},[2351,2352,2353],"ins",{},"Attention"," : Ce point ne fonctionne, par contre, pas si\nl'objet (",[152,2356,270],{},") est un descendant de ",[152,2359,2360],{},"QObject",". En effet ",[152,2363,2360],{},"\ngarde une référence du ",[152,2366,124],{}," en mémoire et lors de la\nréutilisation du ",[152,2369,2360],{}," une erreur indique que l'objet n'a pas été\ndétruit et est déjà utilisé par un ",[152,2372,124],{},". On n'a pas le\nproblème avec ",[152,2375,2376],{},"std::tr1::shared_ptr",[12,2378,2380],{"id":2379},"benchmark","Benchmark",[17,2382,2383,2384,2386],{},"Le but du benchmark est de se faire une idée sur les performances d'une\napplication utilisant des ",[152,2385,124],{}," à la place des pointeurs\nnormaux. Attention, ce bench ne prend pas en compte le besoin potentiel\nde Mutex, de comptage de référence manuel, ... dans les applications\nmulti-thread qui pourrait être nécessaire pour ne pas supprimer le\npointeur si besoin.",[17,2388,2389,2390,2392,2393,95],{},"Dans ce test nous allons tester également (en comparaison), le pointeur\n",[20,2391,35],{}," du C++0x",[37,2394,2395],{},[40,2396,2400],{"href":2397,"ariaDescribedBy":2398,"dataFootnoteRef":45,"id":2399},"#user-content-fn-12",[44],"user-content-fnref-12","12",[17,2402,2403],{},"Nous allons donc tester les opérations courantes de création,\ndestruction, modification, affectation.",[144,2405,2407],{"id":2406},"code-source","Code source",[17,2409,2410,2411,2414],{},"Le code source est disponible, attaché au billet. Dans la suite du\nbillet, seuls les morceaux intéressants du benchmark seront décris. Le\nbenchmark utilise QTest. Nous avons créé un objet bidon ",[152,2412,2413],{},"ObjetTest"," qui\ndans le constructeur allouera un pointeur et remplira une liste, et le\ndestructeur supprime ce pointeur (et forcément la liste).",[17,2416,2417],{},"Pour que chaque test soit indépendant, le jeu de test sera initialisé\navant le début de chaque QBENCHMARK et détruit à la fin du bloc. Nous\naurons quatre méthodes :",[65,2419,2420,2423,2426,2429],{},[68,2421,2422],{},"Allocation",[68,2424,2425],{},"Modification",[68,2427,2428],{},"Affectation",[68,2430,2431],{},"Nettoyage",[17,2433,2434],{},"Pour chaque test nous allons faire le test avec",[65,2436,2437,2440,2448],{},[68,2438,2439],{},"un pointeur C standard",[68,2441,2442,2443,2445,2446],{},"le pointeur ",[152,2444,124],{}," de ",[20,2447,22],{},[68,2449,2442,2450,2445,2452],{},[152,2451,2376],{},[20,2453,2454],{},"C++0x",[17,2456,2457],{},"Pour le test d'allocation et le test de nettoyage, nous allons également\nutiliser l'optimisation possible, vu ci-dessus, d'un Pool d'objet. Nous\nallons faire le test avec :",[65,2459,2460,2466],{},[68,2461,2442,2462,2445,2464],{},[152,2463,124],{},[20,2465,22],{},[68,2467,2442,2468,2445,2470],{},[152,2469,2376],{},[20,2471,2454],{},[144,2473,2475],{"id":2474},"le-jeu-de-test","Le jeu de test",[2477,2478,2480],"h5",{"id":2479},"test-de-lallocation","Test de l'allocation",[17,2482,2483,2484,2486,2487,2489],{},"La création du pointeur en utilisant ",[152,2485,124],{}," instancie le\npointeur ainsi que le ",[152,2488,124],{},". Le temps d'exécution est donc\npotentiellement deux fois plus long (voir le benchmark à la fin de ce\nbillet).",[17,2491,2492],{},"Pour la création du pool, nous allons utiliser une méthode qui créera le\npointeur s'il n'est pas dans le pool, et sinon prendra le pointeur du\npool. Dans notre cas de test, il y aura toujours une valeur dans le\npool, que l'on aura rempli au préalable.",[17,2494,2495,2496,759,2499,2502],{},"La méthode ",[152,2497,2498],{},"createFromPool()",[152,2500,2501],{},"createFromBoostPool()"," est\nsensiblement identique :",[235,2504,2506],{"className":237,"code":2505,"language":239,"meta":45,"style":45},"QSharedPointer\u003CObjetTest> createFromPool()\n{\n    ObjetTest * c_ptr;\n    if (_queue.size())\n    {\n        c_ptr = _queue.dequeue();\n    }\n    else\n    {\n        c_ptr = new ObjetTest();\n    }\n\n    QSharedPointer\u003CObjetTest> ptr(c_ptr, returnToPool);\n    return ptr;\n}\n",[152,2507,2508,2523,2527,2536,2550,2554,2569,2573,2577,2581,2594,2598,2602,2617,2623],{"__ignoreMap":45},[243,2509,2510,2512,2514,2516,2518,2521],{"class":245,"line":246},[243,2511,124],{"class":322},[243,2513,267],{"class":249},[243,2515,2413],{"class":322},[243,2517,410],{"class":249},[243,2519,2520],{"class":276},"createFromPool",[243,2522,1269],{"class":249},[243,2524,2525],{"class":245,"line":253},[243,2526,250],{"class":249},[243,2528,2529,2532,2534],{"class":245,"line":260},[243,2530,2531],{"class":249},"    ObjetTest ",[243,2533,637],{"class":266},[243,2535,2098],{"class":249},[243,2537,2538,2540,2542,2544,2546,2548],{"class":245,"line":291},[243,2539,307],{"class":266},[243,2541,2105],{"class":249},[243,2543,2108],{"class":322},[243,2545,95],{"class":249},[243,2547,2113],{"class":276},[243,2549,2116],{"class":249},[243,2551,2552],{"class":245,"line":298},[243,2553,316],{"class":249},[243,2555,2556,2559,2561,2563,2565,2567],{"class":245,"line":304},[243,2557,2558],{"class":249},"        c_ptr ",[243,2560,510],{"class":266},[243,2562,2130],{"class":322},[243,2564,95],{"class":249},[243,2566,2135],{"class":276},[243,2568,592],{"class":249},[243,2570,2571],{"class":245,"line":313},[243,2572,337],{"class":249},[243,2574,2575],{"class":245,"line":319},[243,2576,2146],{"class":266},[243,2578,2579],{"class":245,"line":334},[243,2580,316],{"class":249},[243,2582,2583,2585,2587,2589,2592],{"class":245,"line":340},[243,2584,2558],{"class":249},[243,2586,510],{"class":266},[243,2588,645],{"class":266},[243,2590,2591],{"class":276}," ObjetTest",[243,2593,592],{"class":249},[243,2595,2596],{"class":245,"line":345},[243,2597,337],{"class":249},[243,2599,2600],{"class":245,"line":351},[243,2601,295],{"emptyLinePlaceholder":294},[243,2603,2604,2606,2608,2610,2612,2614],{"class":245,"line":360},[243,2605,263],{"class":249},[243,2607,267],{"class":266},[243,2609,2413],{"class":249},[243,2611,273],{"class":266},[243,2613,277],{"class":276},[243,2615,2616],{"class":249},"(c_ptr, returnToPool);\n",[243,2618,2619,2621],{"class":245,"line":918},[243,2620,2204],{"class":266},[243,2622,460],{"class":249},[243,2624,2625],{"class":245,"line":923},[243,2626,363],{"class":249},[2628,2629,2630,2643],"table",{},[2631,2632,2633],"thead",{},[2634,2635,2636,2640],"tr",{},[2637,2638,2639],"th",{},"Méthode",[2637,2641,2642],{},"Code",[2644,2645,2646,2657,2667,2677,2687],"tbody",{},[2634,2647,2648,2652],{},[2649,2650,2651],"td",{},"C Pointer",[2649,2653,2654],{},[152,2655,2656],{},"ObjetTest* ptr = new ObjetTest();",[2634,2658,2659,2662],{},[2649,2660,2661],{},"Qt Smart Pointer",[2649,2663,2664],{},[152,2665,2666],{},"QSharedPointer\u003CObjetTest> ptr(new ObjetTest());",[2634,2668,2669,2672],{},[2649,2670,2671],{},"Qt Smart Pointer as Pool",[2649,2673,2674],{},[152,2675,2676],{},"QSharedPointer\u003CObjetTest> ptr = createFromPool ();",[2634,2678,2679,2682],{},[2649,2680,2681],{},"C++0x Smart Pointer",[2649,2683,2684],{},[152,2685,2686],{},"std::tr1::shared_ptr\u003CObjetTest> ptr(new ObjetTest());",[2634,2688,2689,2692],{},[2649,2690,2691],{},"C++0x Smart Pointer as Pool",[2649,2693,2694],{},[152,2695,2696],{},"std::tr1::shared_ptr\u003CObjetTest> ptr = createFromBoostPool ();",[2477,2698,2700],{"id":2699},"test-de-modification-dune-donnée","Test de Modification d'une donnée",[17,2702,2703],{},"Pour la modification d'une donnée, on génère un nombre aléatoire que\nl'on va stocker (toujours le même pour chaque test, cela n'a pas\nd'importance). La génération du nombre aléatoire se fait en dehors du\nbloc, pour éviter de polluer le test avec le calcul d'un nombre\naléatoire. Ici il n'y a pas création d'affectation du pointeur, juste\nune affectation d'une valeur dans le contenu du pointeur. La syntaxe\npour le C, et pour le pointeur intelligent est identique.",[2628,2705,2706,2714],{},[2631,2707,2708],{},[2634,2709,2710,2712],{},[2637,2711,2639],{},[2637,2713,2642],{},[2644,2715,2716],{},[2634,2717,2718,2721],{},[2649,2719,2720],{},"C Pointer \u002F Qt Smart Pointer \u002F C++0x Smart Pointer",[2649,2722,2723],{},[152,2724,2725],{},"obj->value = random_number;",[2477,2727,2729],{"id":2728},"test-daffectation","Test d'affectation",[17,2731,2732,2733,2735],{},"Pour l'affectation nous allons créer une nouvelle variable qui pointera\nsur le même pointeur, et sur lequel on fera une modification. La\ncréation d'un pointeur peut arriver par exemple lors du passage du\npointeur à une fonction, ou lors de la déclaration d'une variable devant\ncontenir la même valeur. Cette déclaration supplémentaire a peu d'impact\npour un pointeur C mais pour un pointeur ",[20,2734,35],{}," oblige la\ncréation d'un objet, et l'incrément d'un nombre d'instance (qu'on\ndécrémente ici dans la même boucle).",[2628,2737,2738,2746],{},[2631,2739,2740],{},[2634,2741,2742,2744],{},[2637,2743,2639],{},[2637,2745,2642],{},[2644,2747,2748,2757,2766,2775,2783,2792],{},[2634,2749,2750,2752],{},[2649,2751,2651],{},[2649,2753,2754],{},[152,2755,2756],{},"ObjetTest * obj2 = obj;",[2634,2758,2759,2761],{},[2649,2760],{},[2649,2762,2763],{},[152,2764,2765],{},"obj2->value = random_number;",[2634,2767,2768,2770],{},[2649,2769,2661],{},[2649,2771,2772],{},[152,2773,2774],{},"QSharedPointer\u003CObjetTest> obj2 = obj;",[2634,2776,2777,2779],{},[2649,2778],{},[2649,2780,2781],{},[152,2782,2765],{},[2634,2784,2785,2787],{},[2649,2786,2681],{},[2649,2788,2789],{},[152,2790,2791],{},"std::tr1::shared_ptr\u003CObjetTest> obj2 = obj;",[2634,2793,2794,2796],{},[2649,2795],{},[2649,2797,2798],{},[152,2799,2765],{},[2477,2801,2803],{"id":2802},"test-de-destruction","Test de destruction",[17,2805,2806,2807,2810],{},"Pour ce test, nous allons initialiser une liste de pointeur, et pour le\nbenchmark, nous allons supprimer un à un chaque élément de la liste.La\ndestruction du pointeur en C se fait par un ",[152,2808,2809],{},"delete",". Pour le pointeur\n''intelligent', il n'y a pas de destruction explicite. Nous allons juste\nsupprimer le pointeur de la liste, le pointeur sera alors\nautomatiquement détruit car il n'y aura plus de référence vers ce\npointeur.",[17,2812,2813,2814,386],{},"Pour le cas de test utilisant la notion du Pool, on aura créé le\npointeur avec le delete ",[152,2815,2816],{},"returnToPool()",[235,2818,2820],{"className":237,"code":2819,"language":239,"meta":45,"style":45},"void returnToPool(ObjetTest *obj)\n{\n    _queue.enqueue(obj);\n}\n",[152,2821,2822,2839,2843,2854],{"__ignoreMap":45},[243,2823,2824,2826,2829,2831,2833,2835,2837],{"class":245,"line":246},[243,2825,396],{"class":266},[243,2827,2828],{"class":276}," returnToPool",[243,2830,280],{"class":249},[243,2832,2413],{"class":322},[243,2834,860],{"class":266},[243,2836,2268],{"class":413},[243,2838,416],{"class":249},[243,2840,2841],{"class":245,"line":253},[243,2842,250],{"class":249},[243,2844,2845,2848,2850,2852],{"class":245,"line":260},[243,2846,2847],{"class":322},"    _queue",[243,2849,95],{"class":249},[243,2851,2308],{"class":276},[243,2853,2311],{"class":249},[243,2855,2856],{"class":245,"line":291},[243,2857,363],{"class":249},[17,2859,2860],{},"Cette méthode ne fait pas de réelle destruction, mais juste un ajout de\nl'objet au pool.",[2628,2862,2863,2871],{},[2631,2864,2865],{},[2634,2866,2867,2869],{},[2637,2868,2639],{},[2637,2870,2642],{},[2644,2872,2873,2882,2891,2900,2906,2912],{},[2634,2874,2875,2877],{},[2649,2876,2651],{},[2649,2878,2879],{},[152,2880,2881],{},"delete c_ptr_list.at(0);",[2634,2883,2884,2886],{},[2649,2885],{},[2649,2887,2888],{},[152,2889,2890],{},"c_ptr_list.removeFirst ();",[2634,2892,2893,2895],{},[2649,2894,2661],{},[2649,2896,2897],{},[152,2898,2899],{},"smart_ptr_list.removeFirst ();",[2634,2901,2902,2904],{},[2649,2903,2671],{},[2649,2905],{},[2634,2907,2908,2910],{},[2649,2909,2681],{},[2649,2911],{},[2634,2913,2914,2916],{},[2649,2915,2691],{},[2649,2917],{},[2477,2919,2921],{"id":2920},"résultat-du-test","Résultat du test",[17,2923,2924],{},"Le test a été fait en utilisant la version 4.6.3 de Qt. Test effectué\npour 5 000 000 itérations.",[2628,2926,2927,2948],{},[2631,2928,2929],{},[2634,2930,2931,2933,2936,2939,2942,2945],{},[2637,2932],{},[2637,2934,2935],{},"Pointeur C",[2637,2937,2938],{},"Pointeur Qt",[2637,2940,2941],{},"Pointeur C++0x",[2637,2943,2944],{},"Pool en utilisant QSharedPointer",[2637,2946,2947],{},"Pool en utilisant std::tr1::shared_ptr",[2644,2949,2950,2971,2989,3007],{},[2634,2951,2952,2956,2959,2962,2965,2968],{},[2649,2953,2954],{},[152,2955,2422],{},[2649,2957,2958],{},"0.0004275 msec",[2649,2960,2961],{},"0.0007692 msec",[2649,2963,2964],{},"0.0006604 msec",[2649,2966,2967],{},"0.0002590 msec",[2649,2969,2970],{},"0.0002286 msec",[2634,2972,2973,2977,2980,2983,2985,2987],{},[2649,2974,2975],{},[152,2976,2425],{},[2649,2978,2979],{},"0.000010 msec",[2649,2981,2982],{},"0.000012 msec",[2649,2984,2982],{},[2649,2986],{},[2649,2988],{},[2634,2990,2991,2995,2997,3000,3003,3005],{},[2649,2992,2993],{},[152,2994,2428],{},[2649,2996,2979],{},[2649,2998,2999],{},"0.0000386 msec",[2649,3001,3002],{},"0.0000230 msec",[2649,3004],{},[2649,3006],{},[2634,3008,3009,3014,3017,3020,3023,3026],{},[2649,3010,3011],{},[152,3012,3013],{},"Destruction",[2649,3015,3016],{},"0.000190 msec",[2649,3018,3019],{},"0.0003161 msec",[2649,3021,3022],{},"0.0003359 msec",[2649,3024,3025],{},"0.0004003 msec",[2649,3027,3028],{},"0.0003601 msec",[17,3030,3031,3032,3034],{},"Conclusion que l'on peut en tirer, le pointeur C est ce qu'il y a de\nplus rapide à partir du moment où on fait de l'allocation de\nl'affectation ou de la destruction. Par contre il n'apporte pas la\nsouplesse qu'apporte les pointeurs ",[20,3033,62],{}," entre autre pour les\napplications multi-threadé.",[17,3036,3037],{},"On remarque que le pointeur C++0x est plus rapide pour la création, mais\napparemment plus lent en destruction. Il est également possible avec le\npool de gagner en performance (surtout en création). Par contre le coût\nde destruction de l'objet n'est pas encore assez fort pour y gagner en\nutilisant le pool.",[17,3039,3040],{},"Ensuite il est important de se faire son propre jugement selon ses\nbesoins. Si besoin le source est attaché, vous pouvez faire vos propres\ntests.",[2477,3042,3044],{"id":3043},"source-du-test","Source du test",[17,3046,3047,3048,95],{},"Vous pouvez trouver les sources du test au ",[40,3049,3051],{"href":3050},"\u002FProgrammation\u002Fqt-performance-de-l-utilisation-de-qsharedpointer\u002Fsmart_benchmark.7z","lien suivant",[17,3053,3054,3059,3060,3065,3066,95],{},[40,3055,3058],{"href":3056,"rel":3057},"http:\u002F\u002Fwww.boost.org\u002Fdoc\u002Flibs\u002F1_45_0\u002Flibs\u002Fsmart_ptr\u002Fshared_ptr.htm",[74],"boost::shared_ptr"," du projet ",[40,3061,3064],{"href":3062,"rel":3063},"http:\u002F\u002Fwww.boost.org\u002F",[74],"Boost",". Boost est une librairie qui\najoute beaucoup de facilité pour les programmes en C++, comme par\nexemple les smart-pointer dont certains seront inclus dans C++0x, ou de\nla boucle ",[152,3067,3068],{},"std::for_each",[3070,3071,3074,3080],"section",{"className":3072,"dataFootnotes":45},[3073],"footnotes",[3075,3076,3079],"h2",{"className":3077,"id":44},[3078],"sr-only","Footnotes",[3081,3082,3083,3094,3103,3114,3133,3142,3155,3164,3176,3185,3199,3208],"ol",{},[68,3084,3086,3087],{"id":3085},"user-content-fn-1","en anglais : smart-pointer ",[40,3088,3093],{"href":3089,"ariaLabel":3090,"className":3091,"dataFootnoteBackref":45},"#user-content-fnref-1","Back to reference 1",[3092],"data-footnote-backref","↩",[68,3095,3097,3098],{"id":3096},"user-content-fn-2","COW = Copy On Write ",[40,3099,3093],{"href":3100,"ariaLabel":3101,"className":3102,"dataFootnoteBackref":45},"#user-content-fnref-2","Back to reference 2",[3092],[68,3104,3106,3107,1971,3109],{"id":3105},"user-content-fn-3","Ce pointeur est l'équivalent du pointeur ",[20,3108,35],{},[40,3110,3093],{"href":3111,"ariaLabel":3112,"className":3113,"dataFootnoteBackref":45},"#user-content-fnref-3","Back to reference 3",[3092],[68,3115,3117,3118,3121,3122,3124,3125,3127,3128],{"id":3116},"user-content-fn-4","Si à un moment donné il faut utiliser le pointeur C pour une\nraison quelconque, on peut utiliser ",[152,3119,3120],{},"ptr.data()"," mais il faut s'assurer\nque le pointeur ne sera pas détruit en déclarant un ",[152,3123,124],{},"\ndans le même bloc utilisant le pointeur C. Le ",[152,3126,124],{}," ne devra\nêtre détruit qu'après utilisation du pointeur C. Ceci peut être fait\ndans certain cas pour des raisons de performance. ",[40,3129,3093],{"href":3130,"ariaLabel":3131,"className":3132,"dataFootnoteBackref":45},"#user-content-fnref-4","Back to reference 4",[3092],[68,3134,3136,3137],{"id":3135},"user-content-fn-5","Sinon nous ne serions plus là pour lancer la méthode ",[40,3138,3093],{"href":3139,"ariaLabel":3140,"className":3141,"dataFootnoteBackref":45},"#user-content-fnref-5","Back to reference 5",[3092],[68,3143,3145,3146,3149,3150],{"id":3144},"user-content-fn-6","Le ",[152,3147,3148],{},"QWeakPointeur"," ne gardant pas d'instance d'objet, car il\nn'incrémente pas le compteur de référence ",[40,3151,3093],{"href":3152,"ariaLabel":3153,"className":3154,"dataFootnoteBackref":45},"#user-content-fnref-6","Back to reference 6",[3092],[68,3156,3158,3159],{"id":3157},"user-content-fn-7","s'il n'existe pas de référence vers l'objet B ailleurs dans\nl'application ",[40,3160,3093],{"href":3161,"ariaLabel":3162,"className":3163,"dataFootnoteBackref":45},"#user-content-fnref-7","Back to reference 7",[3092],[68,3165,3167,3168,3170,3171],{"id":3166},"user-content-fn-8","Attention quand même, ",[152,3169,124],{}," protège le pointeur\nmais pas le contenu ",[40,3172,3093],{"href":3173,"ariaLabel":3174,"className":3175,"dataFootnoteBackref":45},"#user-content-fnref-8","Back to reference 8",[3092],[68,3177,3179,3180],{"id":3178},"user-content-fn-9","d'autres threads pouvant inclure le thread principal ",[40,3181,3093],{"href":3182,"ariaLabel":3183,"className":3184,"dataFootnoteBackref":45},"#user-content-fnref-9","Back to reference 9",[3092],[68,3186,3188,3189,3191,3192,1971,3194],{"id":3187},"user-content-fn-10","Si l'objet est supprimé, ",[152,3190,488],{},", sera alors remis à\n",[152,3193,539],{},[40,3195,3093],{"href":3196,"ariaLabel":3197,"className":3198,"dataFootnoteBackref":45},"#user-content-fnref-10","Back to reference 10",[3092],[68,3200,3202,3203],{"id":3201},"user-content-fn-11","Dans le code en question, il faudrait ajouter la notion de\nmutex autour de la gestion de la queue, en cas de création parallèle. ",[40,3204,3093],{"href":3205,"ariaLabel":3206,"className":3207,"dataFootnoteBackref":45},"#user-content-fnref-11","Back to reference 11",[3092],[68,3209,3211,3212,1971,3214,3217,3218],{"id":3210},"user-content-fn-12","Le pointeur ",[20,3213,35],{},[152,3215,3216],{},"shared_ptr"," de C++0x à pour origine\nle pointeur Boost ",[40,3219,3093],{"href":3220,"ariaLabel":3221,"className":3222,"dataFootnoteBackref":45},"#user-content-fnref-12","Back to reference 12",[3092],[3224,3225,3226],"style",{},"html pre.shiki code .sn6KH, html code.shiki .sn6KH{--shiki-default:#ABB2BF}html pre.shiki code .sV9Aq, html code.shiki .sV9Aq{--shiki-default:#7F848E;--shiki-default-font-style:italic}html pre.shiki code .seHd6, html code.shiki .seHd6{--shiki-default:#C678DD}html pre.shiki code .sVbv2, html code.shiki .sVbv2{--shiki-default:#61AFEF}html pre.shiki code .sU0A5, html code.shiki .sU0A5{--shiki-default:#E5C07B}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .s_ZVi, html code.shiki .s_ZVi{--shiki-default:#E06C75;--shiki-default-font-style:italic}html pre.shiki code .sVyAn, html code.shiki .sVyAn{--shiki-default:#E06C75}",{"title":45,"searchDepth":253,"depth":253,"links":3228},[3229,3230,3231,3232,3233],{"id":14,"depth":260,"text":15},{"id":137,"depth":260,"text":138},{"id":141,"depth":260,"text":142},{"id":2379,"depth":260,"text":2380},{"id":44,"depth":253,"text":3079},"Programmation","programmation","2011-01-25",{"type":9,"value":3238},[3239,3241,3247,3262,3268],[12,3240,15],{"id":14},[17,3242,3243,23,3245,27],{},[20,3244,22],{},[20,3246,26],{},[17,3248,3249,32,3251,3253,48,3258,51,3260,54],{},[20,3250,22],{},[20,3252,35],{},[37,3254,3255],{},[40,3256,47],{"href":42,"ariaDescribedBy":3257,"dataFootnoteRef":45,"id":46},[44],[20,3259,35],{},[20,3261,22],{},[17,3263,3264,59,3266,63],{},[20,3265,22],{},[20,3267,62],{},[65,3269,3270,3285,3295,3300],{},[68,3271,3272,76,3275,82,3278,86,3280,95],{},[40,3273,75],{"href":72,"rel":3274},[74],[40,3276,81],{"href":79,"rel":3277},[74],[20,3279,85],{},[37,3281,3282],{},[40,3283,94],{"href":91,"ariaDescribedBy":3284,"dataFootnoteRef":45,"id":93},[44],[68,3286,3287,76,3290,106,3293,109],{},[40,3288,102],{"href":100,"rel":3289},[74],[40,3291,81],{"href":79,"rel":3292},[74],[20,3294,35],{},[68,3296,3297,117],{},[40,3298,116],{"href":114,"rel":3299},[74],[68,3301,3302,125,3305,134],{},[40,3303,124],{"href":122,"rel":3304},[74],[37,3306,3307],{},[40,3308,133],{"href":130,"ariaDescribedBy":3309,"dataFootnoteRef":45,"id":132},[44],"md","Lille, France",{},"\u002Fpost\u002Fqt-performance-de-l-utilisation-de-qsharedpointer",{"title":6,"description":45},"qt-performance-de-l-utilisation-de-qsharedpointer","posts\u002FProgrammation\u002F2011-01-25-qt-performance-de-l-utilisation-de-qsharedpointer",[3318,3319,3320],"kde","performance","qt","XqeYjPQRtPf9XXPuxti7oBEPUUnQd2DT_XGvWB1Y7Ws",{"id":3323,"title":3324,"author":7,"body":3325,"category":3234,"categorySlug":3235,"date":4566,"description":45,"excerpt":4567,"extension":3310,"location":3311,"meta":4579,"navigation":294,"path":4580,"published":294,"seo":4581,"slug":4582,"stem":4583,"tags":4584,"timeToRead":298,"__hash__":4585},"posts\u002Fposts\u002FProgrammation\u002F2010-12-22-qt-concatenation-de-chaine-de-caracteres.md","C++\u002FQt - Concaténation de chaînes de caractères",{"type":9,"value":3326,"toc":4559},[3327,3329,3332,3335,3338,3341,3345,3352,3411,3421,3424,3428,3435,3447,3453,3515,3525,3534,3596,3598,3607,3609,3617,4512,4514,4517,4539,4542,4545,4549,4556],[12,3328,15],{"id":14},[17,3330,3331],{},"Qt est un framework orienté objet écrit en C++ et permettant de faire\ndes interfaces graphiques à l’aide de ces widgets. Ce framework est\nutilisé par le projet KDE depuis ses débuts pour en faire un\nenvironnement très complet.",[17,3333,3334],{},"Qt permet donc de faire des interfaces graphiques mais aussi d’accéder à\ndes bases de données SQL, de faire de la communication réseau, une\ngestion simplifiée des threads, la lecture de fichier XML. Qt intègre\naussi le moteur HTML Webkit.",[17,3336,3337],{},"Qt ajoute une couche supplémentaire au C++ permettant de faire de\nl’introspection de classe un peu plus poussée (comme l’appel d’une\nméthode dont on ne connaît le nom qu’à l’exécution). Qt permet également\nla gestion d’évènement par l’intermédiaire d’un système puissant de\nSIGNALS et de SLOTS.",[17,3339,3340],{},"Dans la suite de cet article nous allons nous concentrer sur une très\npetite partie de Qt mais qui est utilisée dans beaucoup d’applications\nécrites en Qt : les chaînes de caractères, et plus précisément, la\nconcaténation de chaînes de caractères.",[3075,3342,3344],{"id":3343},"concaténation-de-chaînes-de-caractères","Concaténation de chaînes de caractères",[17,3346,3347,3348,3351],{},"Comme dans d’autres langages, la concaténation de chaînes de caractères\nse fait à l'aide de l'opérateur ",[152,3349,3350],{},"+",". Prenons un exemple simple :",[235,3353,3355],{"className":237,"code":3354,"language":239,"meta":45,"style":45},"#include \u003CQString>\n\nQString abc = \"abc\", def = \"def\";\nQString result;\nresult = abc + def;\n",[152,3356,3357,3366,3370,3391,3396],{"__ignoreMap":45},[243,3358,3359,3362],{"class":245,"line":246},[243,3360,3361],{"class":266},"#include",[243,3363,3365],{"class":3364},"subq3"," \u003CQString>\n",[243,3367,3368],{"class":245,"line":253},[243,3369,295],{"emptyLinePlaceholder":294},[243,3371,3372,3375,3377,3380,3383,3385,3388],{"class":245,"line":260},[243,3373,3374],{"class":249},"QString abc ",[243,3376,510],{"class":266},[243,3378,3379],{"class":3364}," \"abc\"",[243,3381,3382],{"class":249},", def ",[243,3384,510],{"class":266},[243,3386,3387],{"class":3364}," \"def\"",[243,3389,3390],{"class":249},";\n",[243,3392,3393],{"class":245,"line":291},[243,3394,3395],{"class":249},"QString result;\n",[243,3397,3398,3401,3403,3406,3408],{"class":245,"line":298},[243,3399,3400],{"class":249},"result ",[243,3402,510],{"class":266},[243,3404,3405],{"class":249}," abc ",[243,3407,3350],{"class":266},[243,3409,3410],{"class":249}," def;\n",[17,3412,3413,3414,3416,3417,3420],{},"L'utilisation de l'opérateur ",[152,3415,3350],{}," facilite l'écriture de la concaténation\ndes chaînes de caractères (tout comme l'opérateur ",[152,3418,3419],{},"=="," permet de\nfacilement comparer des chaînes de caractères de type QString).",[17,3422,3423],{},"Malheureusement cette écriture rend le code peu performant pour diverses\nraisons (que l’on peut retrouver dans la documentation de l’objet\nQString).",[12,3425,3427],{"id":3426},"concaténation-rapide-de-chaînes-de-caractères","Concaténation rapide de chaînes de caractères",[17,3429,3430,3431,3434],{},"A partir de Qt 4.6, Nokia, a ajouté un ",[152,3432,3433],{},"template"," nommé QStringBuilder\n(cet objet fait beaucoup penser à l'objet StringBuilder de JAVA\npermettant d'accélérer les concaténations de chaînes de caractères).",[17,3436,3437,3438,3441,3442,765,3444,3446],{},"Ce template ne s’utilise pas directement mais au travers de l'opérateur\n",[152,3439,3440],{},"%",". En remplaçant donc l'opérateur ",[152,3443,3350],{},[152,3445,3440],{}," on gagne en performance\n(dixit la doc de Qt).",[17,3448,3449,3450,386],{},"Pour pouvoir utiliser l'opérateur, il suffit d'inclure le fichier\n",[152,3451,3452],{},"QStringBuilder",[235,3454,3456],{"className":237,"code":3455,"language":239,"meta":45,"style":45},"#include \u003CQStringBuilder>\n\nQString abc = \"abc\", def = \"def\", ghi = \"ghi\";\nQString result;\nresult = abc % def % ghi;\n",[152,3457,3458,3465,3469,3493,3497],{"__ignoreMap":45},[243,3459,3460,3462],{"class":245,"line":246},[243,3461,3361],{"class":266},[243,3463,3464],{"class":3364}," \u003CQStringBuilder>\n",[243,3466,3467],{"class":245,"line":253},[243,3468,295],{"emptyLinePlaceholder":294},[243,3470,3471,3473,3475,3477,3479,3481,3483,3486,3488,3491],{"class":245,"line":260},[243,3472,3374],{"class":249},[243,3474,510],{"class":266},[243,3476,3379],{"class":3364},[243,3478,3382],{"class":249},[243,3480,510],{"class":266},[243,3482,3387],{"class":3364},[243,3484,3485],{"class":249},", ghi ",[243,3487,510],{"class":266},[243,3489,3490],{"class":3364}," \"ghi\"",[243,3492,3390],{"class":249},[243,3494,3495],{"class":245,"line":291},[243,3496,3395],{"class":249},[243,3498,3499,3501,3503,3505,3507,3510,3512],{"class":245,"line":298},[243,3500,3400],{"class":249},[243,3502,510],{"class":266},[243,3504,3405],{"class":249},[243,3506,3440],{"class":266},[243,3508,3509],{"class":249}," def ",[243,3511,3440],{"class":266},[243,3513,3514],{"class":249}," ghi;\n",[17,3516,3517,3518,3521,3522,95],{},"Une autre possibilité est de définir (par exemple dans votre fichier\n.pro ou dans un include général de votre application) les définitions\n",[152,3519,3520],{},"QT_USE_FAST_CONCATENATION",", et ",[152,3523,3524],{},"QT_USE_FAST_OPERATOR_PLUS",[17,3526,3527,3528,3530,3531,3533],{},"Ces définitions permettent de remplacer l'opérateur ",[152,3529,3350],{}," par l'opérateur\n",[152,3532,3440],{}," dans toute l'application. Par contre cette opération peut demander\nquelques modifications de votre code.",[235,3535,3537],{"className":237,"code":3536,"language":239,"meta":45,"style":45},"#define QT_USE_FAST_CONCATENATION\n#define QT_USE_FAST_OPERATOR_PLUS\n#include \u003CQString>\n\nQString abc = \"abc\", def = \"def\";\nQString result;\nresult = abc + def;\n",[152,3538,3539,3547,3554,3560,3564,3580,3584],{"__ignoreMap":45},[243,3540,3541,3544],{"class":245,"line":246},[243,3542,3543],{"class":266},"#define",[243,3545,3546],{"class":276}," QT_USE_FAST_CONCATENATION\n",[243,3548,3549,3551],{"class":245,"line":253},[243,3550,3543],{"class":266},[243,3552,3553],{"class":276}," QT_USE_FAST_OPERATOR_PLUS\n",[243,3555,3556,3558],{"class":245,"line":260},[243,3557,3361],{"class":266},[243,3559,3365],{"class":3364},[243,3561,3562],{"class":245,"line":291},[243,3563,295],{"emptyLinePlaceholder":294},[243,3565,3566,3568,3570,3572,3574,3576,3578],{"class":245,"line":298},[243,3567,3374],{"class":249},[243,3569,510],{"class":266},[243,3571,3379],{"class":3364},[243,3573,3382],{"class":249},[243,3575,510],{"class":266},[243,3577,3387],{"class":3364},[243,3579,3390],{"class":249},[243,3581,3582],{"class":245,"line":304},[243,3583,3395],{"class":249},[243,3585,3586,3588,3590,3592,3594],{"class":245,"line":313},[243,3587,3400],{"class":249},[243,3589,510],{"class":266},[243,3591,3405],{"class":249},[243,3593,3350],{"class":266},[243,3595,3410],{"class":249},[12,3597,2380],{"id":2379},[17,3599,3600,3601,3603,3604,3606],{},"Nous allons donc dans la suite du document vérifier que l'opérateur ",[152,3602,3440],{},"\nest plus rapide que l'opérateur ",[152,3605,3350],{},". Pour cela nous allons utiliser le\nmodule de benchmark de Qt.",[144,3608,2407],{"id":2406},[17,3610,3611,3612,3614,3615,95],{},"Voici le petit programme permettant de tester la performance de la\nconcaténation. Notre exemple simple va constituer à la concaténation de\n26 chaînes de caractères créées au début. L'appel se fera une première\nfois en utilisant l'opérateur ",[152,3613,3350],{}," et une seconde fois en utilisant\nl'opérateur ",[152,3616,3440],{},[235,3618,3620],{"className":237,"code":3619,"language":239,"meta":45,"style":45},"#include \u003CQtCore\u002FQString>\n#include \u003CQtTest\u002FQtTest>\n#include \u003CQStringBuilder>\n\nclass TestPerf : public QObject\n{\n    Q_OBJECT\npublic:\n    TestPerf();\nprivate Q_SLOTS:\n    void concat();\n    void concat_data();\n};\n\nTestPerf::TestPerf()\n{\n} \n\nvoid TestPerf::concat()\n{\n    QFETCH(bool, useStringBuilder);\n    QString result;\n    QString a(\"a\"), b(\"b\"), c(\"c\"), d(\"d\"), e(\"e\"), f(\"f\"), g(\"g\"),\n    h(\"h\"), i(\"i\"), j(\"j\"), k(\"k\"), l(\"l\"), m(\"m\"), n(\"n\"), o(\"o\"),\n    p(\"p\"), q(\"q\"), r(\"r\"), s(\"s\"), t(\"t\"), u(\"u\"), v(\"v\"), w(\"w\"),\n    x(\"x\"), y(\"y\"), z(\"z\"); \n\n    if (useStringBuilder)\n    {\n        QBENCHMARK {\n            \u002F\u002F Concaténation en utilisant QStringBuilder\n            \u002F\u002F Dans ce cas la concaténation devrait être plus rapide\n            result = a % b % c % d % e % f % g % h % i % j % k % l %\n            m % n % o % p % q % r % s % t % u % v % w % x % y % z;\n        }\n    }\n    else\n    {\n        QBENCHMARK\n        {\n            \u002F\u002F Concaténation en n'utilisant pas QStringBuilder. On\n            \u002F\u002F utilise alors la concaténation normal de chaînes de\n            \u002F\u002F caractères en utilisant QString\n            result = a + b + c + d + e + f + g + h + i + j + k + l +\n            m + n + o + p + q + r + s + t + u + v + w + x + y + z;\n        }\n    }\n}\n\nvoid TestPerf::concat_data()\n{\n    QTest::addColumn\u003Cbool>(\"useStringBuilder\");\n    QTest::newRow(\"Don't use QStringBuilder\") \u003C\u003C false;\n    QTest::newRow(\"Use QStringBuilder\") \u003C\u003C true;\n}\n\nQTEST_APPLESS_MAIN(TestPerf);\n\n#include \"tst_testperf.moc\"\n",[152,3621,3622,3629,3636,3642,3646,3662,3666,3671,3675,3682,3687,3696,3705,3709,3713,3724,3728,3733,3737,3750,3754,3767,3772,3846,3928,4010,4043,4047,4054,4058,4063,4068,4073,4141,4211,4217,4222,4227,4232,4238,4244,4250,4256,4262,4318,4375,4380,4385,4390,4395,4409,4414,4434,4459,4480,4485,4490,4499,4504],{"__ignoreMap":45},[243,3623,3624,3626],{"class":245,"line":246},[243,3625,3361],{"class":266},[243,3627,3628],{"class":3364}," \u003CQtCore\u002FQString>\n",[243,3630,3631,3633],{"class":245,"line":253},[243,3632,3361],{"class":266},[243,3634,3635],{"class":3364}," \u003CQtTest\u002FQtTest>\n",[243,3637,3638,3640],{"class":245,"line":260},[243,3639,3361],{"class":266},[243,3641,3464],{"class":3364},[243,3643,3644],{"class":245,"line":291},[243,3645,295],{"emptyLinePlaceholder":294},[243,3647,3648,3650,3653,3656,3659],{"class":245,"line":298},[243,3649,983],{"class":266},[243,3651,3652],{"class":322}," TestPerf",[243,3654,3655],{"class":249}," : ",[243,3657,3658],{"class":266},"public",[243,3660,3661],{"class":322}," QObject\n",[243,3663,3664],{"class":245,"line":304},[243,3665,250],{"class":249},[243,3667,3668],{"class":245,"line":313},[243,3669,3670],{"class":249},"    Q_OBJECT\n",[243,3672,3673],{"class":245,"line":319},[243,3674,995],{"class":266},[243,3676,3677,3680],{"class":245,"line":334},[243,3678,3679],{"class":276},"    TestPerf",[243,3681,592],{"class":249},[243,3683,3684],{"class":245,"line":340},[243,3685,3686],{"class":249},"private Q_SLOTS:\n",[243,3688,3689,3691,3694],{"class":245,"line":345},[243,3690,1484],{"class":266},[243,3692,3693],{"class":276}," concat",[243,3695,592],{"class":249},[243,3697,3698,3700,3703],{"class":245,"line":351},[243,3699,1484],{"class":266},[243,3701,3702],{"class":276}," concat_data",[243,3704,592],{"class":249},[243,3706,3707],{"class":245,"line":360},[243,3708,1126],{"class":249},[243,3710,3711],{"class":245,"line":918},[243,3712,295],{"emptyLinePlaceholder":294},[243,3714,3715,3718,3720,3722],{"class":245,"line":923},[243,3716,3717],{"class":322},"TestPerf",[243,3719,797],{"class":249},[243,3721,3717],{"class":276},[243,3723,1269],{"class":249},[243,3725,3726],{"class":245,"line":1108},[243,3727,250],{"class":249},[243,3729,3730],{"class":245,"line":1123},[243,3731,3732],{"class":249},"} \n",[243,3734,3735],{"class":245,"line":1369},[243,3736,295],{"emptyLinePlaceholder":294},[243,3738,3739,3741,3743,3745,3748],{"class":245,"line":1384},[243,3740,396],{"class":266},[243,3742,3652],{"class":322},[243,3744,797],{"class":249},[243,3746,3747],{"class":276},"concat",[243,3749,1269],{"class":249},[243,3751,3752],{"class":245,"line":1397},[243,3753,250],{"class":249},[243,3755,3756,3759,3761,3764],{"class":245,"line":1402},[243,3757,3758],{"class":276},"    QFETCH",[243,3760,280],{"class":249},[243,3762,3763],{"class":266},"bool",[243,3765,3766],{"class":249},", useStringBuilder);\n",[243,3768,3769],{"class":245,"line":1407},[243,3770,3771],{"class":249},"    QString result;\n",[243,3773,3774,3777,3779,3781,3784,3787,3789,3791,3794,3796,3798,3800,3803,3805,3808,3810,3813,3815,3818,3820,3823,3825,3828,3830,3833,3835,3838,3840,3843],{"class":245,"line":1415},[243,3775,3776],{"class":249},"    QString ",[243,3778,40],{"class":276},[243,3780,280],{"class":249},[243,3782,3783],{"class":3364},"\"a\"",[243,3785,3786],{"class":249},"), ",[243,3788,1500],{"class":276},[243,3790,280],{"class":249},[243,3792,3793],{"class":3364},"\"b\"",[243,3795,3786],{"class":249},[243,3797,1677],{"class":276},[243,3799,280],{"class":249},[243,3801,3802],{"class":3364},"\"c\"",[243,3804,3786],{"class":249},[243,3806,3807],{"class":276},"d",[243,3809,280],{"class":249},[243,3811,3812],{"class":3364},"\"d\"",[243,3814,3786],{"class":249},[243,3816,3817],{"class":276},"e",[243,3819,280],{"class":249},[243,3821,3822],{"class":3364},"\"e\"",[243,3824,3786],{"class":249},[243,3826,3827],{"class":276},"f",[243,3829,280],{"class":249},[243,3831,3832],{"class":3364},"\"f\"",[243,3834,3786],{"class":249},[243,3836,3837],{"class":276},"g",[243,3839,280],{"class":249},[243,3841,3842],{"class":3364},"\"g\"",[243,3844,3845],{"class":249},"),\n",[243,3847,3848,3851,3853,3856,3858,3861,3863,3866,3868,3871,3873,3876,3878,3881,3883,3886,3888,3891,3893,3896,3898,3901,3903,3906,3908,3911,3913,3916,3918,3921,3923,3926],{"class":245,"line":1420},[243,3849,3850],{"class":276},"    h",[243,3852,280],{"class":249},[243,3854,3855],{"class":3364},"\"h\"",[243,3857,3786],{"class":249},[243,3859,3860],{"class":276},"i",[243,3862,280],{"class":249},[243,3864,3865],{"class":3364},"\"i\"",[243,3867,3786],{"class":249},[243,3869,3870],{"class":276},"j",[243,3872,280],{"class":249},[243,3874,3875],{"class":3364},"\"j\"",[243,3877,3786],{"class":249},[243,3879,3880],{"class":276},"k",[243,3882,280],{"class":249},[243,3884,3885],{"class":3364},"\"k\"",[243,3887,3786],{"class":249},[243,3889,3890],{"class":276},"l",[243,3892,280],{"class":249},[243,3894,3895],{"class":3364},"\"l\"",[243,3897,3786],{"class":249},[243,3899,3900],{"class":276},"m",[243,3902,280],{"class":249},[243,3904,3905],{"class":3364},"\"m\"",[243,3907,3786],{"class":249},[243,3909,3910],{"class":276},"n",[243,3912,280],{"class":249},[243,3914,3915],{"class":3364},"\"n\"",[243,3917,3786],{"class":249},[243,3919,3920],{"class":276},"o",[243,3922,280],{"class":249},[243,3924,3925],{"class":3364},"\"o\"",[243,3927,3845],{"class":249},[243,3929,3930,3933,3935,3938,3940,3943,3945,3948,3950,3953,3955,3958,3960,3963,3965,3968,3970,3973,3975,3978,3980,3983,3985,3988,3990,3993,3995,3998,4000,4003,4005,4008],{"class":245,"line":1425},[243,3931,3932],{"class":276},"    p",[243,3934,280],{"class":249},[243,3936,3937],{"class":3364},"\"p\"",[243,3939,3786],{"class":249},[243,3941,3942],{"class":276},"q",[243,3944,280],{"class":249},[243,3946,3947],{"class":3364},"\"q\"",[243,3949,3786],{"class":249},[243,3951,3952],{"class":276},"r",[243,3954,280],{"class":249},[243,3956,3957],{"class":3364},"\"r\"",[243,3959,3786],{"class":249},[243,3961,3962],{"class":276},"s",[243,3964,280],{"class":249},[243,3966,3967],{"class":3364},"\"s\"",[243,3969,3786],{"class":249},[243,3971,3972],{"class":276},"t",[243,3974,280],{"class":249},[243,3976,3977],{"class":3364},"\"t\"",[243,3979,3786],{"class":249},[243,3981,3982],{"class":276},"u",[243,3984,280],{"class":249},[243,3986,3987],{"class":3364},"\"u\"",[243,3989,3786],{"class":249},[243,3991,3992],{"class":276},"v",[243,3994,280],{"class":249},[243,3996,3997],{"class":3364},"\"v\"",[243,3999,3786],{"class":249},[243,4001,4002],{"class":276},"w",[243,4004,280],{"class":249},[243,4006,4007],{"class":3364},"\"w\"",[243,4009,3845],{"class":249},[243,4011,4012,4015,4017,4020,4022,4025,4027,4030,4032,4035,4037,4040],{"class":245,"line":1442},[243,4013,4014],{"class":276},"    x",[243,4016,280],{"class":249},[243,4018,4019],{"class":3364},"\"x\"",[243,4021,3786],{"class":249},[243,4023,4024],{"class":276},"y",[243,4026,280],{"class":249},[243,4028,4029],{"class":3364},"\"y\"",[243,4031,3786],{"class":249},[243,4033,4034],{"class":276},"z",[243,4036,280],{"class":249},[243,4038,4039],{"class":3364},"\"z\"",[243,4041,4042],{"class":249},"); \n",[243,4044,4045],{"class":245,"line":1447},[243,4046,295],{"emptyLinePlaceholder":294},[243,4048,4049,4051],{"class":245,"line":1469},[243,4050,307],{"class":266},[243,4052,4053],{"class":249}," (useStringBuilder)\n",[243,4055,4056],{"class":245,"line":1476},[243,4057,316],{"class":249},[243,4059,4060],{"class":245,"line":1481},[243,4061,4062],{"class":249},"        QBENCHMARK {\n",[243,4064,4065],{"class":245,"line":1506},[243,4066,4067],{"class":256},"            \u002F\u002F Concaténation en utilisant QStringBuilder\n",[243,4069,4070],{"class":245,"line":1522},[243,4071,4072],{"class":256},"            \u002F\u002F Dans ce cas la concaténation devrait être plus rapide\n",[243,4074,4075,4078,4080,4083,4085,4088,4090,4093,4095,4098,4100,4103,4105,4108,4110,4113,4115,4118,4120,4123,4125,4128,4130,4133,4135,4138],{"class":245,"line":1527},[243,4076,4077],{"class":249},"            result ",[243,4079,510],{"class":266},[243,4081,4082],{"class":249}," a ",[243,4084,3440],{"class":266},[243,4086,4087],{"class":249}," b ",[243,4089,3440],{"class":266},[243,4091,4092],{"class":249}," c ",[243,4094,3440],{"class":266},[243,4096,4097],{"class":249}," d ",[243,4099,3440],{"class":266},[243,4101,4102],{"class":249}," e ",[243,4104,3440],{"class":266},[243,4106,4107],{"class":249}," f ",[243,4109,3440],{"class":266},[243,4111,4112],{"class":249}," g ",[243,4114,3440],{"class":266},[243,4116,4117],{"class":249}," h ",[243,4119,3440],{"class":266},[243,4121,4122],{"class":249}," i ",[243,4124,3440],{"class":266},[243,4126,4127],{"class":249}," j ",[243,4129,3440],{"class":266},[243,4131,4132],{"class":249}," k ",[243,4134,3440],{"class":266},[243,4136,4137],{"class":249}," l ",[243,4139,4140],{"class":266},"%\n",[243,4142,4143,4146,4148,4151,4153,4156,4158,4161,4163,4166,4168,4171,4173,4176,4178,4181,4183,4186,4188,4191,4193,4196,4198,4201,4203,4206,4208],{"class":245,"line":1541},[243,4144,4145],{"class":249},"            m ",[243,4147,3440],{"class":266},[243,4149,4150],{"class":249}," n ",[243,4152,3440],{"class":266},[243,4154,4155],{"class":249}," o ",[243,4157,3440],{"class":266},[243,4159,4160],{"class":249}," p ",[243,4162,3440],{"class":266},[243,4164,4165],{"class":249}," q ",[243,4167,3440],{"class":266},[243,4169,4170],{"class":249}," r ",[243,4172,3440],{"class":266},[243,4174,4175],{"class":249}," s ",[243,4177,3440],{"class":266},[243,4179,4180],{"class":249}," t ",[243,4182,3440],{"class":266},[243,4184,4185],{"class":249}," u ",[243,4187,3440],{"class":266},[243,4189,4190],{"class":249}," v ",[243,4192,3440],{"class":266},[243,4194,4195],{"class":249}," w ",[243,4197,3440],{"class":266},[243,4199,4200],{"class":249}," x ",[243,4202,3440],{"class":266},[243,4204,4205],{"class":249}," y ",[243,4207,3440],{"class":266},[243,4209,4210],{"class":249}," z;\n",[243,4212,4214],{"class":245,"line":4213},35,[243,4215,4216],{"class":249},"        }\n",[243,4218,4220],{"class":245,"line":4219},36,[243,4221,337],{"class":249},[243,4223,4225],{"class":245,"line":4224},37,[243,4226,2146],{"class":266},[243,4228,4230],{"class":245,"line":4229},38,[243,4231,316],{"class":249},[243,4233,4235],{"class":245,"line":4234},39,[243,4236,4237],{"class":249},"        QBENCHMARK\n",[243,4239,4241],{"class":245,"line":4240},40,[243,4242,4243],{"class":249},"        {\n",[243,4245,4247],{"class":245,"line":4246},41,[243,4248,4249],{"class":256},"            \u002F\u002F Concaténation en n'utilisant pas QStringBuilder. On\n",[243,4251,4253],{"class":245,"line":4252},42,[243,4254,4255],{"class":256},"            \u002F\u002F utilise alors la concaténation normal de chaînes de\n",[243,4257,4259],{"class":245,"line":4258},43,[243,4260,4261],{"class":256},"            \u002F\u002F caractères en utilisant QString\n",[243,4263,4265,4267,4269,4271,4273,4275,4277,4279,4281,4283,4285,4287,4289,4291,4293,4295,4297,4299,4301,4303,4305,4307,4309,4311,4313,4315],{"class":245,"line":4264},44,[243,4266,4077],{"class":249},[243,4268,510],{"class":266},[243,4270,4082],{"class":249},[243,4272,3350],{"class":266},[243,4274,4087],{"class":249},[243,4276,3350],{"class":266},[243,4278,4092],{"class":249},[243,4280,3350],{"class":266},[243,4282,4097],{"class":249},[243,4284,3350],{"class":266},[243,4286,4102],{"class":249},[243,4288,3350],{"class":266},[243,4290,4107],{"class":249},[243,4292,3350],{"class":266},[243,4294,4112],{"class":249},[243,4296,3350],{"class":266},[243,4298,4117],{"class":249},[243,4300,3350],{"class":266},[243,4302,4122],{"class":249},[243,4304,3350],{"class":266},[243,4306,4127],{"class":249},[243,4308,3350],{"class":266},[243,4310,4132],{"class":249},[243,4312,3350],{"class":266},[243,4314,4137],{"class":249},[243,4316,4317],{"class":266},"+\n",[243,4319,4321,4323,4325,4327,4329,4331,4333,4335,4337,4339,4341,4343,4345,4347,4349,4351,4353,4355,4357,4359,4361,4363,4365,4367,4369,4371,4373],{"class":245,"line":4320},45,[243,4322,4145],{"class":249},[243,4324,3350],{"class":266},[243,4326,4150],{"class":249},[243,4328,3350],{"class":266},[243,4330,4155],{"class":249},[243,4332,3350],{"class":266},[243,4334,4160],{"class":249},[243,4336,3350],{"class":266},[243,4338,4165],{"class":249},[243,4340,3350],{"class":266},[243,4342,4170],{"class":249},[243,4344,3350],{"class":266},[243,4346,4175],{"class":249},[243,4348,3350],{"class":266},[243,4350,4180],{"class":249},[243,4352,3350],{"class":266},[243,4354,4185],{"class":249},[243,4356,3350],{"class":266},[243,4358,4190],{"class":249},[243,4360,3350],{"class":266},[243,4362,4195],{"class":249},[243,4364,3350],{"class":266},[243,4366,4200],{"class":249},[243,4368,3350],{"class":266},[243,4370,4205],{"class":249},[243,4372,3350],{"class":266},[243,4374,4210],{"class":249},[243,4376,4378],{"class":245,"line":4377},46,[243,4379,4216],{"class":249},[243,4381,4383],{"class":245,"line":4382},47,[243,4384,337],{"class":249},[243,4386,4388],{"class":245,"line":4387},48,[243,4389,363],{"class":249},[243,4391,4393],{"class":245,"line":4392},49,[243,4394,295],{"emptyLinePlaceholder":294},[243,4396,4398,4400,4402,4404,4407],{"class":245,"line":4397},50,[243,4399,396],{"class":266},[243,4401,3652],{"class":322},[243,4403,797],{"class":249},[243,4405,4406],{"class":276},"concat_data",[243,4408,1269],{"class":249},[243,4410,4412],{"class":245,"line":4411},51,[243,4413,250],{"class":249},[243,4415,4417,4420,4423,4425,4427,4429,4432],{"class":245,"line":4416},52,[243,4418,4419],{"class":249},"    QTest::",[243,4421,4422],{"class":276},"addColumn",[243,4424,267],{"class":249},[243,4426,3763],{"class":266},[243,4428,910],{"class":249},[243,4430,4431],{"class":3364},"\"useStringBuilder\"",[243,4433,1503],{"class":249},[243,4435,4437,4439,4442,4444,4447,4450,4453,4457],{"class":245,"line":4436},53,[243,4438,4419],{"class":249},[243,4440,4441],{"class":276},"newRow",[243,4443,280],{"class":249},[243,4445,4446],{"class":3364},"\"Don't use QStringBuilder\"",[243,4448,4449],{"class":249},") ",[243,4451,4452],{"class":266},"\u003C\u003C",[243,4454,4456],{"class":4455},"sVC51"," false",[243,4458,3390],{"class":249},[243,4460,4462,4464,4466,4468,4471,4473,4475,4478],{"class":245,"line":4461},54,[243,4463,4419],{"class":249},[243,4465,4441],{"class":276},[243,4467,280],{"class":249},[243,4469,4470],{"class":3364},"\"Use QStringBuilder\"",[243,4472,4449],{"class":249},[243,4474,4452],{"class":266},[243,4476,4477],{"class":4455}," true",[243,4479,3390],{"class":249},[243,4481,4483],{"class":245,"line":4482},55,[243,4484,363],{"class":249},[243,4486,4488],{"class":245,"line":4487},56,[243,4489,295],{"emptyLinePlaceholder":294},[243,4491,4493,4496],{"class":245,"line":4492},57,[243,4494,4495],{"class":276},"QTEST_APPLESS_MAIN",[243,4497,4498],{"class":249},"(TestPerf);\n",[243,4500,4502],{"class":245,"line":4501},58,[243,4503,295],{"emptyLinePlaceholder":294},[243,4505,4507,4509],{"class":245,"line":4506},59,[243,4508,3361],{"class":266},[243,4510,4511],{"class":3364}," \"tst_testperf.moc\"\n",[144,4513,2921],{"id":2920},[17,4515,4516],{},"Le test a été fait en utilisant la version 4.6.3 de Qt. Le résultat est\nsensiblement le même avec la version 4.7.0",[2628,4518,4519,4529],{},[2631,4520,4521],{},[2634,4522,4523,4526],{},[2637,4524,4525],{},"Sans QStringBuilder",[2637,4527,4528],{},"Avec QStringBuilder",[2644,4530,4531],{},[2634,4532,4533,4536],{},[2649,4534,4535],{},"0.00367 msec",[2649,4537,4538],{},"0.00046 msec",[17,4540,4541],{},"On voit dans ce test que la version en utilisant QStringBuilder est 8\nfois plus rapide que sans. Bien sûr vu le temps que prend la\nconcaténation de chaînes de caractères, ce test commence à avoir de\nl'intérêt uniquement à partir du moment où on fait beaucoup de\nconcaténation dans la seconde, ou si les temps de réponses sont\ncritiques.",[17,4543,4544],{},"Sur ce, je vous souhaite à tous un Joyeux noël et une bonne année.",[144,4546,4548],{"id":4547},"le-programme","Le programme",[17,4550,4551,4552,95],{},"Vous pouvez trouver le programme ",[40,4553,4555],{"href":4554},"\u002FProgrammation\u002Fqt-concatenation-de-chaine-de-caracteres\u002Ftest-perfconcat.7z","ici",[3224,4557,4558],{},"html pre.shiki code .seHd6, html code.shiki .seHd6{--shiki-default:#C678DD}html pre.shiki code .subq3, html code.shiki .subq3{--shiki-default:#98C379}html pre.shiki code .sn6KH, html code.shiki .sn6KH{--shiki-default:#ABB2BF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sVbv2, html code.shiki .sVbv2{--shiki-default:#61AFEF}html pre.shiki code .sU0A5, html code.shiki .sU0A5{--shiki-default:#E5C07B}html pre.shiki code .sV9Aq, html code.shiki .sV9Aq{--shiki-default:#7F848E;--shiki-default-font-style:italic}html pre.shiki code .sVC51, html code.shiki .sVC51{--shiki-default:#D19A66}",{"title":45,"searchDepth":253,"depth":253,"links":4560},[4561,4562],{"id":14,"depth":260,"text":15},{"id":3343,"depth":253,"text":3344,"children":4563},[4564,4565],{"id":3426,"depth":260,"text":3427},{"id":2379,"depth":260,"text":2380},"2010-12-22",{"type":9,"value":4568},[4569,4571,4573,4575,4577],[12,4570,15],{"id":14},[17,4572,3331],{},[17,4574,3334],{},[17,4576,3337],{},[17,4578,3340],{},{},"\u002Fpost\u002Fqt-concatenation-de-chaine-de-caracteres",{"title":3324,"description":45},"qt-concatenation-de-chaine-de-caracteres","posts\u002FProgrammation\u002F2010-12-22-qt-concatenation-de-chaine-de-caracteres",[3319,3320],"tnYQV8OJKsLZvtUPPbMHph26Eitmdp4-hd-STXhGP2A",{"id":4587,"title":4588,"author":7,"body":4589,"category":3234,"categorySlug":3235,"date":6242,"description":45,"excerpt":6243,"extension":3310,"location":3311,"meta":6278,"navigation":294,"path":6279,"published":294,"seo":6280,"slug":6281,"stem":6282,"tags":6283,"timeToRead":313,"__hash__":6284},"posts\u002Fposts\u002FProgrammation\u002F2010-06-06-calcul-de-la-distance.md","Calcul de la distance entre deux fichiers",{"type":9,"value":4590,"toc":6236},[4591,4593,4602,4610,4618,4639,4641,4644,4647,4650,4653,4656,4659,4674,4685,4688,4703,4706,4722,4726,4740,4743,5240,5243,5352,6202,6205,6208,6215,6233],[12,4592,15],{"id":14},[17,4594,4595,4596,4601],{},"Suite à un ",[40,4597,4600],{"href":4598,"rel":4599},"http:\u002F\u002Flinuxfr.org\u002Fforums\u002F20\u002F28366.html",[74],"billet sur LinuxFR",", où je demandais comment calculer la\ndistance (ou le pourcentage de similitude entre deux logiciels), j'ai\nobtenu la formule suivante :",[235,4603,4608],{"className":4604,"code":4606,"language":4607},[4605],"language-text","distance = 1 - ( C(A) + C(B) - C(AB) ) \u002F Max(C(A), C(B))\n","text",[152,4609,4606],{"__ignoreMap":45},[17,4611,4612,4613,95],{},"où C(X) est la taille du fichier X compressé",[37,4614,4615],{},[40,4616,47],{"href":42,"ariaDescribedBy":4617,"dataFootnoteRef":45,"id":46},[44],[17,4619,4620,4621,4624,4625,759,4628,4631,4632,4634,4635,4638],{},"Après avoir testé les formats ",[152,4622,4623],{},"gzip",", ",[152,4626,4627],{},"bzip2",[152,4629,4630],{},"lzma",", j'ai conclu que\nle format de compression le plus performant pour le calcul, est le\nformat ",[152,4633,4630],{},", car le dictionnaire avec ",[20,4636,4637],{},"la mise en commun"," était le\nplus gros, et donc le calcul de distance est plus efficace.",[12,4640,4548],{"id":4547},[17,4642,4643],{},"J'ai donc décidé d'écrire un programme parcourant un dossier (avec\nplusieurs milliers de fichiers) et de calculer pour toutes les\ncombinaisons des fichiers la distance entre chaque fichier. Ce programme\nconsommant énormément de mémoire, il se peut que pour un grand nombre de\nfichier, le programme se plante avec une erreur d'allocation de mémoire.",[17,4645,4646],{},"Ce programme permet de pouvoir faire une cartographie de ces fichiers et\nainsi de pouvoir les classer. Testé sur des fichiers textes (sources de\nlogiciels), le programme est assez efficace.",[17,4648,4649],{},"Testé sur des images, ou des vidéos, les fichiers sont considérés comme\ntous éloignés les uns des autres, même s'ils sont identiques à\ncompression différente près, ou s'ils sont identiques à un mouvement\nprès sur la photo (du genre une photo où une même personne se tient dans\nune position différente).",[17,4651,4652],{},"Si vous avez une idée sur comment calculer la distance entre deux\nfichiers déjà compressés (avec perte qui plus est), ca m'intéresse. :)",[17,4654,4655],{},"Comme l'exécution est très lente (compression lzma niveau 9), le\nprogramme peut être arrêté et redémarré.",[17,4657,4658],{},"Pour démarrer le programme, il faut exécuter la commande :",[235,4660,4664],{"className":4661,"code":4662,"language":4663,"meta":45,"style":45},"language-bash shiki shiki-themes one-dark-pro",".\u002Fcalcul_distance \u002Fmon\u002Fdossier\n","bash",[152,4665,4666],{"__ignoreMap":45},[243,4667,4668,4671],{"class":245,"line":246},[243,4669,4670],{"class":276},".\u002Fcalcul_distance",[243,4672,4673],{"class":3364}," \u002Fmon\u002Fdossier\n",[17,4675,4676,4677,4680,4681,4684],{},"Le programme va alors créer un fichier\n",[152,4678,4679],{},"{5ac1fd3c-504f-4110-9f7e-d6fc89e57bdb}.db"," où\n",[152,4682,4683],{},"{5ac1fd3c-504f-4110-9f7e-d6fc89e57bdb}"," est différent à chaque nouveau\nlancement.",[17,4686,4687],{},"Pour reprendre le traitement où il était, il suffit alors de lancer :",[235,4689,4691],{"className":4661,"code":4690,"language":4663,"meta":45,"style":45},".\u002Fcalcul_distance --uuid {5ac1fd3c-504f-4110-9f7e-d6fc89e57bdb}\n",[152,4692,4693],{"__ignoreMap":45},[243,4694,4695,4697,4700],{"class":245,"line":246},[243,4696,4670],{"class":276},[243,4698,4699],{"class":4455}," --uuid",[243,4701,4702],{"class":3364}," {5ac1fd3c-504f-4110-9f7e-d6fc89e57bdb}\n",[17,4704,4705],{},"Si on veut ajouter un dossier au traitement après coup :",[235,4707,4709],{"className":4661,"code":4708,"language":4663,"meta":45,"style":45},".\u002Fcalcul_distance \u002Fnouveau\u002Fdossier --uuid {5ac1fd3c-504f-4110-9f7e-d6fc89e57bdb}\n",[152,4710,4711],{"__ignoreMap":45},[243,4712,4713,4715,4718,4720],{"class":245,"line":246},[243,4714,4670],{"class":276},[243,4716,4717],{"class":3364}," \u002Fnouveau\u002Fdossier",[243,4719,4699],{"class":4455},[243,4721,4702],{"class":3364},[12,4723,4725],{"id":4724},"exemple","Exemple",[17,4727,4728,4729,4732,4733,4735,4736,4739],{},"Par exemple soit les différentes versions d'un logiciel, mis dans des\narchives ",[152,4730,4731],{},"tar",". Pour ne prendre que le code source des versions, on va\nsupprimer tous les fichiers suivants de l'archive ",[152,4734,4731],{}," :\n",[152,4737,4738],{},"*.jpg, *.png, *.ico, *.qm, *.db",", ... les sources externes à\nl'application. On ne garde donc que les fichiers textes dont nous avons\nla possession.",[17,4741,4742],{},"Après le nettoyage des dossiers :",[235,4744,4746],{"className":4661,"code":4745,"language":4663,"meta":45,"style":45},"$ for i in `ls` ; do\n> tar -c $i\u002F*\n> $i.tar\n> done\n$ ls -l\n-rw-r--r-- 1 phoenix phoenix 2,5M  6 juin  13:24 v0.6.10.tar\n-rw-r--r-- 1 phoenix phoenix 440K  6 juin  13:24 v0.6.4.tar\n-rw-r--r-- 1 phoenix phoenix 530K  6 juin  13:24 v0.6.5.tar\n-rw-r--r-- 1 phoenix phoenix 610K  6 juin  13:24 v0.6.6.tar\n-rw-r--r-- 1 phoenix phoenix 690K  6 juin  13:24 v0.6.7.tar\n-rw-r--r-- 1 phoenix phoenix 1,2M  6 juin  13:24 v0.6.8.tar\n-rw-r--r-- 1 phoenix phoenix 1,3M  6 juin  13:24 v0.6.9.tar\n-rw-r--r-- 1 phoenix phoenix 2,9M  6 juin  13:24 v0.7.0.tar\n-rw-r--r-- 1 phoenix phoenix 2,2M  6 juin  13:24 v0.7.1.tar\n-rw-r--r-- 1 phoenix phoenix 3,3M  6 juin  13:24 v0.7.2.tar\n-rw-r--r-- 1 phoenix phoenix 3,3M  6 juin  13:24 v0.8.0.tar\n-rw-r--r-- 1 phoenix phoenix 3,1M  6 juin  13:24 v0.8.1_services.tar\n-rw-r--r-- 1 phoenix phoenix 3,1M  6 juin  13:24 v0.8.1.tar\n-rw-r--r-- 1 phoenix phoenix 3,8M  6 juin  13:24 v0.9.0.tar\n$ cd ..\n$ calcul_distance .\u002Fxinx\u002F\nStep 0 : Create database\nStep 1 : Create file list\nStep 2 : Compress single file\nStep 3 : Compress pair file\n$ ls\n{051b93a0-d9a9-4778-ac73-81ee01a3905d}.db\nxinx\n$ sqlite3 {051b93a0-d9a9-4778-ac73-81ee01a3905d}.db\n",[152,4747,4748,4777,4788,4797,4804,4814,4842,4864,4886,4908,4930,4952,4974,4996,5018,5040,5061,5083,5104,5126,5136,5146,5163,5179,5197,5213,5220,5225,5230],{"__ignoreMap":45},[243,4749,4750,4753,4756,4759,4762,4765,4768,4771,4774],{"class":245,"line":246},[243,4751,4752],{"class":276},"$",[243,4754,4755],{"class":3364}," for",[243,4757,4758],{"class":3364}," i",[243,4760,4761],{"class":3364}," in",[243,4763,4764],{"class":3364}," `",[243,4766,4767],{"class":276},"ls",[243,4769,4770],{"class":3364},"`",[243,4772,4773],{"class":249}," ; ",[243,4775,4776],{"class":266},"do\n",[243,4778,4779,4782,4785],{"class":245,"line":253},[243,4780,4781],{"class":249},"> tar -c ",[243,4783,4784],{"class":453},"$i",[243,4786,4787],{"class":249},"\u002F*\n",[243,4789,4790,4792,4794],{"class":245,"line":260},[243,4791,410],{"class":249},[243,4793,4784],{"class":453},[243,4795,4796],{"class":249},".tar\n",[243,4798,4799,4801],{"class":245,"line":291},[243,4800,410],{"class":249},[243,4802,4803],{"class":266},"done\n",[243,4805,4806,4808,4811],{"class":245,"line":298},[243,4807,4752],{"class":276},[243,4809,4810],{"class":3364}," ls",[243,4812,4813],{"class":4455}," -l\n",[243,4815,4816,4819,4822,4825,4827,4830,4833,4836,4839],{"class":245,"line":304},[243,4817,4818],{"class":276},"-rw-r--r--",[243,4820,4821],{"class":4455}," 1",[243,4823,4824],{"class":3364}," phoenix",[243,4826,4824],{"class":3364},[243,4828,4829],{"class":3364}," 2,5M",[243,4831,4832],{"class":4455},"  6",[243,4834,4835],{"class":3364}," juin",[243,4837,4838],{"class":3364},"  13:24",[243,4840,4841],{"class":3364}," v0.6.10.tar\n",[243,4843,4844,4846,4848,4850,4852,4855,4857,4859,4861],{"class":245,"line":313},[243,4845,4818],{"class":276},[243,4847,4821],{"class":4455},[243,4849,4824],{"class":3364},[243,4851,4824],{"class":3364},[243,4853,4854],{"class":3364}," 440K",[243,4856,4832],{"class":4455},[243,4858,4835],{"class":3364},[243,4860,4838],{"class":3364},[243,4862,4863],{"class":3364}," v0.6.4.tar\n",[243,4865,4866,4868,4870,4872,4874,4877,4879,4881,4883],{"class":245,"line":319},[243,4867,4818],{"class":276},[243,4869,4821],{"class":4455},[243,4871,4824],{"class":3364},[243,4873,4824],{"class":3364},[243,4875,4876],{"class":3364}," 530K",[243,4878,4832],{"class":4455},[243,4880,4835],{"class":3364},[243,4882,4838],{"class":3364},[243,4884,4885],{"class":3364}," v0.6.5.tar\n",[243,4887,4888,4890,4892,4894,4896,4899,4901,4903,4905],{"class":245,"line":334},[243,4889,4818],{"class":276},[243,4891,4821],{"class":4455},[243,4893,4824],{"class":3364},[243,4895,4824],{"class":3364},[243,4897,4898],{"class":3364}," 610K",[243,4900,4832],{"class":4455},[243,4902,4835],{"class":3364},[243,4904,4838],{"class":3364},[243,4906,4907],{"class":3364}," v0.6.6.tar\n",[243,4909,4910,4912,4914,4916,4918,4921,4923,4925,4927],{"class":245,"line":340},[243,4911,4818],{"class":276},[243,4913,4821],{"class":4455},[243,4915,4824],{"class":3364},[243,4917,4824],{"class":3364},[243,4919,4920],{"class":3364}," 690K",[243,4922,4832],{"class":4455},[243,4924,4835],{"class":3364},[243,4926,4838],{"class":3364},[243,4928,4929],{"class":3364}," v0.6.7.tar\n",[243,4931,4932,4934,4936,4938,4940,4943,4945,4947,4949],{"class":245,"line":345},[243,4933,4818],{"class":276},[243,4935,4821],{"class":4455},[243,4937,4824],{"class":3364},[243,4939,4824],{"class":3364},[243,4941,4942],{"class":3364}," 1,2M",[243,4944,4832],{"class":4455},[243,4946,4835],{"class":3364},[243,4948,4838],{"class":3364},[243,4950,4951],{"class":3364}," v0.6.8.tar\n",[243,4953,4954,4956,4958,4960,4962,4965,4967,4969,4971],{"class":245,"line":351},[243,4955,4818],{"class":276},[243,4957,4821],{"class":4455},[243,4959,4824],{"class":3364},[243,4961,4824],{"class":3364},[243,4963,4964],{"class":3364}," 1,3M",[243,4966,4832],{"class":4455},[243,4968,4835],{"class":3364},[243,4970,4838],{"class":3364},[243,4972,4973],{"class":3364}," v0.6.9.tar\n",[243,4975,4976,4978,4980,4982,4984,4987,4989,4991,4993],{"class":245,"line":360},[243,4977,4818],{"class":276},[243,4979,4821],{"class":4455},[243,4981,4824],{"class":3364},[243,4983,4824],{"class":3364},[243,4985,4986],{"class":3364}," 2,9M",[243,4988,4832],{"class":4455},[243,4990,4835],{"class":3364},[243,4992,4838],{"class":3364},[243,4994,4995],{"class":3364}," v0.7.0.tar\n",[243,4997,4998,5000,5002,5004,5006,5009,5011,5013,5015],{"class":245,"line":918},[243,4999,4818],{"class":276},[243,5001,4821],{"class":4455},[243,5003,4824],{"class":3364},[243,5005,4824],{"class":3364},[243,5007,5008],{"class":3364}," 2,2M",[243,5010,4832],{"class":4455},[243,5012,4835],{"class":3364},[243,5014,4838],{"class":3364},[243,5016,5017],{"class":3364}," v0.7.1.tar\n",[243,5019,5020,5022,5024,5026,5028,5031,5033,5035,5037],{"class":245,"line":923},[243,5021,4818],{"class":276},[243,5023,4821],{"class":4455},[243,5025,4824],{"class":3364},[243,5027,4824],{"class":3364},[243,5029,5030],{"class":3364}," 3,3M",[243,5032,4832],{"class":4455},[243,5034,4835],{"class":3364},[243,5036,4838],{"class":3364},[243,5038,5039],{"class":3364}," v0.7.2.tar\n",[243,5041,5042,5044,5046,5048,5050,5052,5054,5056,5058],{"class":245,"line":1108},[243,5043,4818],{"class":276},[243,5045,4821],{"class":4455},[243,5047,4824],{"class":3364},[243,5049,4824],{"class":3364},[243,5051,5030],{"class":3364},[243,5053,4832],{"class":4455},[243,5055,4835],{"class":3364},[243,5057,4838],{"class":3364},[243,5059,5060],{"class":3364}," v0.8.0.tar\n",[243,5062,5063,5065,5067,5069,5071,5074,5076,5078,5080],{"class":245,"line":1123},[243,5064,4818],{"class":276},[243,5066,4821],{"class":4455},[243,5068,4824],{"class":3364},[243,5070,4824],{"class":3364},[243,5072,5073],{"class":3364}," 3,1M",[243,5075,4832],{"class":4455},[243,5077,4835],{"class":3364},[243,5079,4838],{"class":3364},[243,5081,5082],{"class":3364}," v0.8.1_services.tar\n",[243,5084,5085,5087,5089,5091,5093,5095,5097,5099,5101],{"class":245,"line":1369},[243,5086,4818],{"class":276},[243,5088,4821],{"class":4455},[243,5090,4824],{"class":3364},[243,5092,4824],{"class":3364},[243,5094,5073],{"class":3364},[243,5096,4832],{"class":4455},[243,5098,4835],{"class":3364},[243,5100,4838],{"class":3364},[243,5102,5103],{"class":3364}," v0.8.1.tar\n",[243,5105,5106,5108,5110,5112,5114,5117,5119,5121,5123],{"class":245,"line":1384},[243,5107,4818],{"class":276},[243,5109,4821],{"class":4455},[243,5111,4824],{"class":3364},[243,5113,4824],{"class":3364},[243,5115,5116],{"class":3364}," 3,8M",[243,5118,4832],{"class":4455},[243,5120,4835],{"class":3364},[243,5122,4838],{"class":3364},[243,5124,5125],{"class":3364}," v0.9.0.tar\n",[243,5127,5128,5130,5133],{"class":245,"line":1397},[243,5129,4752],{"class":276},[243,5131,5132],{"class":3364}," cd",[243,5134,5135],{"class":3364}," ..\n",[243,5137,5138,5140,5143],{"class":245,"line":1402},[243,5139,4752],{"class":276},[243,5141,5142],{"class":3364}," calcul_distance",[243,5144,5145],{"class":3364}," .\u002Fxinx\u002F\n",[243,5147,5148,5151,5154,5157,5160],{"class":245,"line":1407},[243,5149,5150],{"class":276},"Step",[243,5152,5153],{"class":4455}," 0",[243,5155,5156],{"class":3364}," :",[243,5158,5159],{"class":3364}," Create",[243,5161,5162],{"class":3364}," database\n",[243,5164,5165,5167,5169,5171,5173,5176],{"class":245,"line":1415},[243,5166,5150],{"class":276},[243,5168,4821],{"class":4455},[243,5170,5156],{"class":3364},[243,5172,5159],{"class":3364},[243,5174,5175],{"class":3364}," file",[243,5177,5178],{"class":3364}," list\n",[243,5180,5181,5183,5186,5188,5191,5194],{"class":245,"line":1420},[243,5182,5150],{"class":276},[243,5184,5185],{"class":4455}," 2",[243,5187,5156],{"class":3364},[243,5189,5190],{"class":3364}," Compress",[243,5192,5193],{"class":3364}," single",[243,5195,5196],{"class":3364}," file\n",[243,5198,5199,5201,5204,5206,5208,5211],{"class":245,"line":1425},[243,5200,5150],{"class":276},[243,5202,5203],{"class":4455}," 3",[243,5205,5156],{"class":3364},[243,5207,5190],{"class":3364},[243,5209,5210],{"class":3364}," pair",[243,5212,5196],{"class":3364},[243,5214,5215,5217],{"class":245,"line":1442},[243,5216,4752],{"class":276},[243,5218,5219],{"class":3364}," ls\n",[243,5221,5222],{"class":245,"line":1447},[243,5223,5224],{"class":249},"{051b93a0-d9a9-4778-ac73-81ee01a3905d}.db\n",[243,5226,5227],{"class":245,"line":1469},[243,5228,5229],{"class":276},"xinx\n",[243,5231,5232,5234,5237],{"class":245,"line":1476},[243,5233,4752],{"class":276},[243,5235,5236],{"class":3364}," sqlite3",[243,5238,5239],{"class":3364}," {051b93a0-d9a9-4778-ac73-81ee01a3905d}.db\n",[17,5241,5242],{},"Nous allons maintenant faire une requête dans la base de données sqlite :",[235,5244,5248],{"className":5245,"code":5246,"language":5247,"meta":45,"style":45},"language-sql shiki shiki-themes one-dark-pro","$ .TABLES\ndistances  files\n$ SELECT files1.path, files2.path, distances.distance FROM distances, files files1, files files2 WHERE distances.id1=files1.id AND distances.id2=files2.id ORDER BY distance ASC;\n","sql",[152,5249,5250,5255,5260],{"__ignoreMap":45},[243,5251,5252],{"class":245,"line":246},[243,5253,5254],{"class":249},"$ .TABLES\n",[243,5256,5257],{"class":245,"line":253},[243,5258,5259],{"class":249},"distances  files\n",[243,5261,5262,5265,5268,5271,5273,5276,5278,5281,5283,5285,5287,5290,5292,5295,5298,5301,5304,5307,5309,5312,5315,5318,5320,5323,5326,5328,5330,5333,5335,5337,5339,5341,5344,5347,5350],{"class":245,"line":260},[243,5263,5264],{"class":249},"$ ",[243,5266,5267],{"class":266},"SELECT",[243,5269,5270],{"class":4455}," files1",[243,5272,95],{"class":249},[243,5274,5275],{"class":4455},"path",[243,5277,4624],{"class":249},[243,5279,5280],{"class":4455},"files2",[243,5282,95],{"class":249},[243,5284,5275],{"class":4455},[243,5286,4624],{"class":249},[243,5288,5289],{"class":4455},"distances",[243,5291,95],{"class":249},[243,5293,5294],{"class":4455},"distance",[243,5296,5297],{"class":266}," FROM",[243,5299,5300],{"class":249}," distances, files files1, files files2 ",[243,5302,5303],{"class":266},"WHERE",[243,5305,5306],{"class":4455}," distances",[243,5308,95],{"class":249},[243,5310,5311],{"class":4455},"id1",[243,5313,510],{"class":5314},"sjrmR",[243,5316,5317],{"class":4455},"files1",[243,5319,95],{"class":249},[243,5321,5322],{"class":4455},"id",[243,5324,5325],{"class":266}," AND",[243,5327,5306],{"class":4455},[243,5329,95],{"class":249},[243,5331,5332],{"class":4455},"id2",[243,5334,510],{"class":5314},[243,5336,5280],{"class":4455},[243,5338,95],{"class":249},[243,5340,5322],{"class":4455},[243,5342,5343],{"class":266}," ORDER BY",[243,5345,5346],{"class":249}," distance ",[243,5348,5349],{"class":266},"ASC",[243,5351,3390],{"class":249},[2628,5353,5354,5367],{},[2631,5355,5356],{},[2634,5357,5358,5361,5364],{},[2637,5359,5360],{},"Version 1",[2637,5362,5363],{},"Version 2",[2637,5365,5366],{},"Distance",[2644,5368,5369,5380,5391,5401,5410,5421,5431,5441,5452,5462,5471,5480,5489,5498,5508,5517,5526,5536,5545,5554,5563,5572,5581,5590,5599,5608,5617,5626,5635,5644,5653,5662,5671,5680,5689,5698,5707,5716,5725,5734,5743,5752,5761,5770,5779,5788,5797,5806,5815,5824,5833,5842,5851,5860,5869,5878,5887,5896,5905,5914,5923,5932,5941,5950,5959,5968,5977,5986,5995,6004,6013,6022,6031,6040,6049,6058,6067,6076,6085,6094,6103,6112,6121,6130,6139,6148,6157,6166,6175,6184,6193],{},[2634,5370,5371,5374,5377],{},[2649,5372,5373],{},"v0.8.1",[2649,5375,5376],{},"v0.8.1_services",[2649,5378,5379],{},"0.0350740694634633",[2634,5381,5382,5385,5388],{},[2649,5383,5384],{},"v0.6.8",[2649,5386,5387],{},"v0.6.9",[2649,5389,5390],{},"0.132275346477201",[2634,5392,5393,5396,5398],{},[2649,5394,5395],{},"v0.8.0",[2649,5397,5373],{},[2649,5399,5400],{},"0.142321125298336",[2634,5402,5403,5405,5407],{},[2649,5404,5395],{},[2649,5406,5376],{},[2649,5408,5409],{},"0.161719318637048",[2634,5411,5412,5415,5418],{},[2649,5413,5414],{},"v0.6.5",[2649,5416,5417],{},"v0.6.6",[2649,5419,5420],{},"0.196933113059686",[2634,5422,5423,5426,5428],{},[2649,5424,5425],{},"v0.6.4",[2649,5427,5414],{},[2649,5429,5430],{},"0.231812199675573",[2634,5432,5433,5435,5438],{},[2649,5434,5417],{},[2649,5436,5437],{},"v0.6.7",[2649,5439,5440],{},"0.266593999923953",[2634,5442,5443,5446,5449],{},[2649,5444,5445],{},"v0.6.10",[2649,5447,5448],{},"v0.7.0",[2649,5450,5451],{},"0.27412838729727",[2634,5453,5454,5457,5459],{},[2649,5455,5456],{},"v0.7.2",[2649,5458,5395],{},[2649,5460,5461],{},"0.312111739912996",[2634,5463,5464,5466,5468],{},[2649,5465,5414],{},[2649,5467,5437],{},[2649,5469,5470],{},"0.351347925829225",[2634,5472,5473,5475,5477],{},[2649,5474,5425],{},[2649,5476,5417],{},[2649,5478,5479],{},"0.364115163581424",[2634,5481,5482,5484,5486],{},[2649,5483,5456],{},[2649,5485,5373],{},[2649,5487,5488],{},"0.386971922637303",[2634,5490,5491,5493,5495],{},[2649,5492,5456],{},[2649,5494,5376],{},[2649,5496,5497],{},"0.401055941017259",[2634,5499,5500,5503,5505],{},[2649,5501,5502],{},"v0.7.1",[2649,5504,5456],{},[2649,5506,5507],{},"0.436705836223058",[2634,5509,5510,5512,5514],{},[2649,5511,5448],{},[2649,5513,5502],{},[2649,5515,5516],{},"0.465121645779551",[2634,5518,5519,5521,5523],{},[2649,5520,5425],{},[2649,5522,5437],{},[2649,5524,5525],{},"0.468472350726879",[2634,5527,5528,5530,5533],{},[2649,5529,5376],{},[2649,5531,5532],{},"v0.9.0",[2649,5534,5535],{},"0.516795574578859",[2634,5537,5538,5540,5542],{},[2649,5539,5373],{},[2649,5541,5532],{},[2649,5543,5544],{},"0.51733623689019",[2634,5546,5547,5549,5551],{},[2649,5548,5395],{},[2649,5550,5532],{},[2649,5552,5553],{},"0.544376861655528",[2634,5555,5556,5558,5560],{},[2649,5557,5437],{},[2649,5559,5384],{},[2649,5561,5562],{},"0.558824765667689",[2634,5564,5565,5567,5569],{},[2649,5566,5502],{},[2649,5568,5395],{},[2649,5570,5571],{},"0.560609480175814",[2634,5573,5574,5576,5578],{},[2649,5575,5445],{},[2649,5577,5387],{},[2649,5579,5580],{},"0.594036969567445",[2634,5582,5583,5585,5587],{},[2649,5584,5502],{},[2649,5586,5373],{},[2649,5588,5589],{},"0.604226316444666",[2634,5591,5592,5594,5596],{},[2649,5593,5502],{},[2649,5595,5376],{},[2649,5597,5598],{},"0.613613062086946",[2634,5600,5601,5603,5605],{},[2649,5602,5437],{},[2649,5604,5387],{},[2649,5606,5607],{},"0.622950487834501",[2634,5609,5610,5612,5614],{},[2649,5611,5448],{},[2649,5613,5456],{},[2649,5615,5616],{},"0.631060763867616",[2634,5618,5619,5621,5623],{},[2649,5620,5445],{},[2649,5622,5502],{},[2649,5624,5625],{},"0.632444883185258",[2634,5627,5628,5630,5632],{},[2649,5629,5445],{},[2649,5631,5384],{},[2649,5633,5634],{},"0.637234847328374",[2634,5636,5637,5639,5641],{},[2649,5638,5417],{},[2649,5640,5384],{},[2649,5642,5643],{},"0.6494052372746",[2634,5645,5646,5648,5650],{},[2649,5647,5387],{},[2649,5649,5502],{},[2649,5651,5652],{},"0.666200571812458",[2634,5654,5655,5657,5659],{},[2649,5656,5456],{},[2649,5658,5532],{},[2649,5660,5661],{},"0.678423568871868",[2634,5663,5664,5666,5668],{},[2649,5665,5414],{},[2649,5667,5384],{},[2649,5669,5670],{},"0.692250570944195",[2634,5672,5673,5675,5677],{},[2649,5674,5384],{},[2649,5676,5502],{},[2649,5678,5679],{},"0.701063946130892",[2634,5681,5682,5684,5686],{},[2649,5683,5417],{},[2649,5685,5387],{},[2649,5687,5688],{},"0.701698986545754",[2634,5690,5691,5693,5695],{},[2649,5692,5387],{},[2649,5694,5448],{},[2649,5696,5697],{},"0.717262408423359",[2634,5699,5700,5702,5704],{},[2649,5701,5448],{},[2649,5703,5395],{},[2649,5705,5706],{},"0.720311680104721",[2634,5708,5709,5711,5713],{},[2649,5710,5414],{},[2649,5712,5387],{},[2649,5714,5715],{},"0.738013305804084",[2634,5717,5718,5720,5722],{},[2649,5719,5425],{},[2649,5721,5384],{},[2649,5723,5724],{},"0.747495551539097",[2634,5726,5727,5729,5731],{},[2649,5728,5445],{},[2649,5730,5456],{},[2649,5732,5733],{},"0.747929200720491",[2634,5735,5736,5738,5740],{},[2649,5737,5384],{},[2649,5739,5448],{},[2649,5741,5742],{},"0.748031544518325",[2634,5744,5745,5747,5749],{},[2649,5746,5448],{},[2649,5748,5373],{},[2649,5750,5751],{},"0.758510349354368",[2634,5753,5754,5756,5758],{},[2649,5755,5448],{},[2649,5757,5376],{},[2649,5759,5760],{},"0.767204482779187",[2634,5762,5763,5765,5767],{},[2649,5764,5425],{},[2649,5766,5387],{},[2649,5768,5769],{},"0.772451857549627",[2634,5771,5772,5774,5776],{},[2649,5773,5445],{},[2649,5775,5395],{},[2649,5777,5778],{},"0.796649043913944",[2634,5780,5781,5783,5785],{},[2649,5782,5502],{},[2649,5784,5532],{},[2649,5786,5787],{},"0.801221496333008",[2634,5789,5790,5792,5794],{},[2649,5791,5387],{},[2649,5793,5456],{},[2649,5795,5796],{},"0.804765901655414",[2634,5798,5799,5801,5803],{},[2649,5800,5384],{},[2649,5802,5456],{},[2649,5804,5805],{},"0.819917045496318",[2634,5807,5808,5810,5812],{},[2649,5809,5445],{},[2649,5811,5373],{},[2649,5813,5814],{},"0.823540395867048",[2634,5816,5817,5819,5821],{},[2649,5818,5445],{},[2649,5820,5376],{},[2649,5822,5823],{},"0.831055117394626",[2634,5825,5826,5828,5830],{},[2649,5827,5445],{},[2649,5829,5437],{},[2649,5831,5832],{},"0.838850951377793",[2634,5834,5835,5837,5839],{},[2649,5836,5387],{},[2649,5838,5395],{},[2649,5840,5841],{},"0.849001032539087",[2634,5843,5844,5846,5848],{},[2649,5845,5437],{},[2649,5847,5502],{},[2649,5849,5850],{},"0.853848016623182",[2634,5852,5853,5855,5857],{},[2649,5854,5448],{},[2649,5856,5532],{},[2649,5858,5859],{},"0.860291356912217",[2634,5861,5862,5864,5866],{},[2649,5863,5384],{},[2649,5865,5395],{},[2649,5867,5868],{},"0.86075956509228",[2634,5870,5871,5873,5875],{},[2649,5872,5445],{},[2649,5874,5417],{},[2649,5876,5877],{},"0.863340151908353",[2634,5879,5880,5882,5884],{},[2649,5881,5387],{},[2649,5883,5373],{},[2649,5885,5886],{},"0.872265541006983",[2634,5888,5889,5891,5893],{},[2649,5890,5417],{},[2649,5892,5502],{},[2649,5894,5895],{},"0.873275579233521",[2634,5897,5898,5900,5902],{},[2649,5899,5445],{},[2649,5901,5414],{},[2649,5903,5904],{},"0.875332023895544",[2634,5906,5907,5909,5911],{},[2649,5908,5387],{},[2649,5910,5376],{},[2649,5912,5913],{},"0.87987037883801",[2634,5915,5916,5918,5920],{},[2649,5917,5437],{},[2649,5919,5448],{},[2649,5921,5922],{},"0.879941907871053",[2634,5924,5925,5927,5929],{},[2649,5926,5384],{},[2649,5928,5373],{},[2649,5930,5931],{},"0.881174812987336",[2634,5933,5934,5936,5938],{},[2649,5935,5414],{},[2649,5937,5502],{},[2649,5939,5940],{},"0.886172606121206",[2634,5942,5943,5945,5947],{},[2649,5944,5384],{},[2649,5946,5376],{},[2649,5948,5949],{},"0.889515283880001",[2634,5951,5952,5954,5956],{},[2649,5953,5445],{},[2649,5955,5425],{},[2649,5957,5958],{},"0.892364892140999",[2634,5960,5961,5963,5965],{},[2649,5962,5417],{},[2649,5964,5448],{},[2649,5966,5967],{},"0.894375709613201",[2634,5969,5970,5972,5974],{},[2649,5971,5445],{},[2649,5973,5532],{},[2649,5975,5976],{},"0.895694726039398",[2634,5978,5979,5981,5983],{},[2649,5980,5437],{},[2649,5982,5456],{},[2649,5984,5985],{},"0.898582911617307",[2634,5987,5988,5990,5992],{},[2649,5989,5425],{},[2649,5991,5502],{},[2649,5993,5994],{},"0.902038058337369",[2634,5996,5997,5999,6001],{},[2649,5998,5414],{},[2649,6000,5448],{},[2649,6002,6003],{},"0.904821831317442",[2634,6005,6006,6008,6010],{},[2649,6007,5417],{},[2649,6009,5456],{},[2649,6011,6012],{},"0.910637046476578",[2634,6014,6015,6017,6019],{},[2649,6016,5425],{},[2649,6018,5448],{},[2649,6020,6021],{},"0.918347943544789",[2634,6023,6024,6026,6028],{},[2649,6025,5414],{},[2649,6027,5456],{},[2649,6029,6030],{},"0.919716704855963",[2634,6032,6033,6035,6037],{},[2649,6034,5387],{},[2649,6036,5532],{},[2649,6038,6039],{},"0.921714099772221",[2634,6041,6042,6044,6046],{},[2649,6043,5437],{},[2649,6045,5395],{},[2649,6047,6048],{},"0.924717744438112",[2634,6050,6051,6053,6055],{},[2649,6052,5384],{},[2649,6054,5532],{},[2649,6056,6057],{},"0.925849165227404",[2634,6059,6060,6062,6064],{},[2649,6061,5425],{},[2649,6063,5456],{},[2649,6065,6066],{},"0.928888262611658",[2634,6068,6069,6071,6073],{},[2649,6070,5437],{},[2649,6072,5373],{},[2649,6074,6075],{},"0.933685479216414",[2634,6077,6078,6080,6082],{},[2649,6079,5417],{},[2649,6081,5395],{},[2649,6083,6084],{},"0.933940067594635",[2634,6086,6087,6089,6091],{},[2649,6088,5437],{},[2649,6090,5376],{},[2649,6092,6093],{},"0.939898268404416",[2634,6095,6096,6098,6100],{},[2649,6097,5414],{},[2649,6099,5395],{},[2649,6101,6102],{},"0.940789807767177",[2634,6104,6105,6107,6109],{},[2649,6106,5417],{},[2649,6108,5373],{},[2649,6110,6111],{},"0.94210246370087",[2634,6113,6114,6116,6118],{},[2649,6115,5417],{},[2649,6117,5376],{},[2649,6119,6120],{},"0.946464528845253",[2634,6122,6123,6125,6127],{},[2649,6124,5425],{},[2649,6126,5395],{},[2649,6128,6129],{},"0.948830071149278",[2634,6131,6132,6134,6136],{},[2649,6133,5414],{},[2649,6135,5373],{},[2649,6137,6138],{},"0.94922082772201",[2634,6140,6141,6143,6145],{},[2649,6142,5414],{},[2649,6144,5376],{},[2649,6146,6147],{},"0.951278461132112",[2634,6149,6150,6152,6154],{},[2649,6151,5425],{},[2649,6153,5373],{},[2649,6155,6156],{},"0.955572468114482",[2634,6158,6159,6161,6163],{},[2649,6160,5425],{},[2649,6162,5376],{},[2649,6164,6165],{},"0.95567206186826",[2634,6167,6168,6170,6172],{},[2649,6169,5437],{},[2649,6171,5532],{},[2649,6173,6174],{},"0.96084453455483",[2634,6176,6177,6179,6181],{},[2649,6178,5417],{},[2649,6180,5532],{},[2649,6182,6183],{},"0.964619158469125",[2634,6185,6186,6188,6190],{},[2649,6187,5414],{},[2649,6189,5532],{},[2649,6191,6192],{},"0.965955795849916",[2634,6194,6195,6197,6199],{},[2649,6196,5425],{},[2649,6198,5532],{},[2649,6200,6201],{},"0.968866861905835",[17,6203,6204],{},"On peut ainsi voir d'après ce tableau, les versions ayant peu de\ndifférences et celles qui ont fait des plus gros bonds en avant.",[17,6206,6207],{},"On voit ainsi qu'il y a plus de différences entre la version 0.8.0 et la\n0.9.0, qu'il y en a eu entre la version 0.6.8 et la 0.6.9. On peut\négalement voir que les versions 0.6.4 et 0.9.0 n'ont plus rien à voir\nentre elles.",[17,6209,6210,6211,95],{},"Vous pouvez télécharger le programme attaché à ",[40,6212,6214],{"href":6213},"\u002FProgrammation\u002Fcalcul-de-la-distance\u002Fcalcul_distance.7z","ce lien",[3070,6216,6218,6221],{"className":6217,"dataFootnotes":45},[3073],[3075,6219,3079],{"className":6220,"id":44},[3078],[3081,6222,6223],{},[68,6224,6225,6226,1971,6230],{"id":3085},"On peut retrouver l'explication de cette formule ",[40,6227,4555],{"href":6228,"rel":6229},"http:\u002F\u002Finterstices.info\u002Fjcms\u002Fc_21828\u002Fclasser-musiques-langues-images-textes-et-genomes",[74],[40,6231,3093],{"href":3089,"ariaLabel":3090,"className":6232,"dataFootnoteBackref":45},[3092],[3224,6234,6235],{},"html pre.shiki code .sVbv2, html code.shiki .sVbv2{--shiki-default:#61AFEF}html pre.shiki code .subq3, html code.shiki .subq3{--shiki-default:#98C379}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sVC51, html code.shiki .sVC51{--shiki-default:#D19A66}html pre.shiki code .sn6KH, html code.shiki .sn6KH{--shiki-default:#ABB2BF}html pre.shiki code .seHd6, html code.shiki .seHd6{--shiki-default:#C678DD}html pre.shiki code .sVyAn, html code.shiki .sVyAn{--shiki-default:#E06C75}html pre.shiki code .sjrmR, html code.shiki .sjrmR{--shiki-default:#56B6C2}",{"title":45,"searchDepth":253,"depth":253,"links":6237},[6238,6239,6240,6241],{"id":14,"depth":260,"text":15},{"id":4547,"depth":260,"text":4548},{"id":4724,"depth":260,"text":4725},{"id":44,"depth":253,"text":3079},"2010-06-06",{"type":9,"value":6244},[6245,6247,6252,6257,6264,6276],[12,6246,15],{"id":14},[17,6248,4595,6249,4601],{},[40,6250,4600],{"href":4598,"rel":6251},[74],[235,6253,6255],{"className":6254,"code":4606,"language":4607},[4605],[152,6256,4606],{"__ignoreMap":45},[17,6258,4612,6259,95],{},[37,6260,6261],{},[40,6262,47],{"href":42,"ariaDescribedBy":6263,"dataFootnoteRef":45,"id":46},[44],[17,6265,4620,6266,4624,6268,759,6270,4631,6272,4634,6274,4638],{},[152,6267,4623],{},[152,6269,4627],{},[152,6271,4630],{},[152,6273,4630],{},[20,6275,4637],{},[3224,6277,6235],{},{},"\u002Fpost\u002Fcalcul-de-la-distance",{"title":4588,"description":45},"calcul-de-la-distance","posts\u002FProgrammation\u002F2010-06-06-calcul-de-la-distance",[3320,3319],"f5dJI_rOrb9a2Kflve8ejZKhwpF_zkBfNrrcWae0dOg",{"id":6286,"title":6287,"author":7,"body":6288,"category":3234,"categorySlug":3235,"date":7471,"description":6292,"excerpt":7472,"extension":3310,"location":3311,"meta":7480,"navigation":294,"path":7481,"published":294,"seo":7482,"slug":7483,"stem":7484,"tags":7485,"timeToRead":313,"__hash__":7487},"posts\u002Fposts\u002FProgrammation\u002F2009-05-31-parseur-xml.md","Parseur XML",{"type":9,"value":6289,"toc":7465},[6290,6293,6300,6303,6307,6310,6313,6316,6319,6323,6326,6329,6373,6382,6526,6529,6532,6535,6541,6545,6548,6562,6565,6569,6582,6585,6591,6594,6600,6603,6607,6610,6613,7275,7289,7292,7298,7301,7442,7462],[17,6291,6292],{},"Bonjours à tous,",[17,6294,6295,6296,6299],{},"L'utilisation des fichiers XML est, à ce jour, un fait dans la plupart\ndes logiciels et est fortement à la mode. Une entreprise qui ne fait pas\nun peu de XML est souvent ",[20,6297,6298],{},"has-been",". On utilise alors le XML à bon ou\nmauvais escient.",[3224,6301,6302],{},"\nth {background-color: #E4E4E4;weigh: bold;}\n .veryslow {background-color: #FF0000;}\n .slow {background-color: #FF8686;}\n .good {background-color: #C3FFC7;}\n .ignored {background-color: #E4E4E4;}\n",[12,6304,6306],{"id":6305},"avantages-inconvénients","Avantages \u002F Inconvénients",[17,6308,6309],{},"Pourquoi utiliser les fichiers XML ? Les fichiers XML sont, pour\ncommencer, des fichiers textes, il seront donc toujours lisibles, ce qui\ngarantit une meilleur pérennité de l'information. Les fichiers XML sont\nstructurés hiérarchiquement et suivent une syntaxe stricte. Ainsi le XML\nest lisible informatiquement par les différents langages de\nprogrammation existant, pour organiser vos données, en utilisant\ndifférents niveaux. Les fichiers XML peuvent être commenté ce qui peut\naméliorer la lisibilité pour un humain.",[17,6311,6312],{},"Le gros inconvénient du XML est sa verbosité. Pour chaque noeud dans la\nhiérarchie, il y a une balise de début, et une balise de fin contenant\nle nom de la balise. Le fichier est moins compact que s'il avait été\nécrit en binaire. Cela peut poser des problèmes comme alourdir les\ncommunications réseaux (ex: pour les webservices). Le fichier est aussi\nplus long à lire qu'un fichier binaire et peut contenir des erreurs.",[17,6314,6315],{},"Si le fichier n'a pas besoin d'être hiérarchique, il est possible\nd'utiliser une structure de fichier INI pour ses données.",[17,6317,6318],{},"Nous nous arrêterons là pour les avantages\u002Finconvénients. L'utilisation\nou non d'un fichier XML est ensuite une question (besoin, éthique, ...)\nà se poser pour ses données et la nécessité de pouvoir les lire\nautrement que par le programme lui-même.",[12,6320,6322],{"id":6321},"performance-des-parseurs","Performance des parseurs.",[17,6324,6325],{},"Je me suis amusé à effectuer le test de lecture de différents fichiers\nde donnée au format XML de taille différentes par une variété de parseur\nXML en construisant si possible un arbre DOM. Le but est donc de créer\nun objet par noeud\u002Fattribut du fichier XML et de reconstituer la\nhiérarchie.",[17,6327,6328],{},"Les parseurs choisis pour ce test sont :",[65,6330,6331,6337,6343,6349,6355,6361,6367],{},[68,6332,6333,6336],{},[2348,6334,6335],{},"QtXml"," : Le module XML de la librairie Qt (de la société Nokia)",[68,6338,6339,6342],{},[2348,6340,6341],{},"LibXml2"," : Une librairie C permettant de faire du parsing XML en\nutilisant DOM ou SAX",[68,6344,6345,6348],{},[2348,6346,6347],{},"LibExpat"," : Un parseur orienté flux (plus proche de la méthode\nSAX que du DOM)",[68,6350,6351,6354],{},[2348,6352,6353],{},"SCEW"," : Un parseur basé sur Expat générant un arbre DOM (donc un\npeu plus comparable aux autre parseur).",[68,6356,6357,6360],{},[2348,6358,6359],{},"TinyXML"," : Encore un autre parseur XML",[68,6362,6363,6366],{},[2348,6364,6365],{},"Xerces-C++"," : Le parseur XML d’Apache",[68,6368,6369,6372],{},[2348,6370,6371],{},"Oracle XML Parser"," : Le parseur d’Oracle propriétaire utiliser\ndans le serveur d’application.",[17,6374,6375,6376,6381],{},"Pour faire cette suite de benchmark",[37,6377,6378],{},[40,6379,47],{"href":42,"ariaDescribedBy":6380,"dataFootnoteRef":45,"id":46},[44],", j’ai utilisé la librairie\nQTestLib de Nokia\u002FQt. Je vous offre donc en avant première le résultat\nde ce test :",[2628,6383,6385,6389],{"style":6384},"width:100%",[6386,6387,6388],"caption",{},"Temps de lecture d'un fichier XML en ms",[2644,6390,6391,6407,6425,6444,6463,6478,6494,6512],{},[2634,6392,6393,6396,6399,6400,6403,6404,6399],{},[2649,6394,6395],{},"               ",[2637,6397,6398],{},"250k","                     ",[2637,6401,6402],{},"9300k","                      ",[2637,6405,6406],{},"11300k",[2634,6408,6409,6412,6417,6421],{},[2637,6410,6411],{},"Qt DOM         ",[2649,6413,6416],{"className":6414},[6415],"veryslow","41,42 ms",[2649,6418,6420],{"className":6419},[6415],"2184,34 ms",[2649,6422,6424],{"className":6423},[6415],"2648,71 ms",[2634,6426,6427,6430,6433,6434,6439,6440,6439],{},[2637,6428,6429],{},"LibXML2        ",[2649,6431,6432],{},"16,55 ms","                 ",[2649,6435,6438],{"className":6436},[6437],"good","710,09 ms","     ",[2649,6441,6443],{"className":6442},[6437],"874,42 ms",[2634,6445,6446,6449,6454,6455,6454,6459,6454],{},[2637,6447,6448],{},"Expat (SAX)    ",[2649,6450,6453],{"className":6451},[6452],"ignored","5,95 ms","  ",[2649,6456,6458],{"className":6457},[6452],"312,02 ms",[2649,6460,6462],{"className":6461},[6452],"393,58 ms",[2634,6464,6465,6468,6433,6471,6474,6475,6433],{},[2637,6466,6467],{},"Oracle         ",[2649,6469,6470],{},"23,24 ms",[2649,6472,6473],{},"928,93 ms","                  ",[2649,6476,6477],{},"1135,86 ms",[2634,6479,6480,6483,6487,6488,6474,6491,6433],{},[2637,6481,6482],{},"Scew           ",[2649,6484,6486],{"className":6485},[6437],"12,05 ms","    ",[2649,6489,6490],{},"944,37 ms",[2649,6492,6493],{},"1184,46 ms",[2634,6495,6496,6499,6487,6504,6439,6508,6439],{},[2637,6497,6498],{},"Tiny XML       ",[2649,6500,6503],{"className":6501},[6502],"slow","28,91 ms",[2649,6505,6507],{"className":6506},[6502],"1101,8 ms",[2649,6509,6511],{"className":6510},[6502],"1369,8 ms",[2634,6513,6514,6517,6433,6520,6474,6523,6474],{},[2637,6515,6516],{},"Xerces (Apache)",[2649,6518,6519],{},"25,03 ms",[2649,6521,6522],{},"742,22 ms",[2649,6524,6525],{},"904,62 ms",[17,6527,6528],{},"La conclusion de ce résultat signifie que le parseur inclu dans Qt (pour\nla construction d'un arbre DOM) est très lent ;). Mais pour une\nutilisation dans une interface graphique, sur de petits fichiers, ne\ndevrait pas poser de problème.",[17,6530,6531],{},"Enfin le parseur le plus rapide (pour les gros fichiers) est Libxml2. Le\nparseur C d'oracle, bien que propriétaire n'a rien d'exceptionnel (si on\ncompte avec les problèmes présenté également ci-dessous). Peut-être que\nla version Java est elle plus performante.",[17,6533,6534],{},"Vous pouvez retrouver quelques graphiques ci-dessous :",[17,6536,6537],{},[176,6538],{"alt":6539,"src":6540},"TestXMLPerf","\u002FProgrammation\u002Fparseur-xml\u002FTestXMLPerf.png",[12,6542,6544],{"id":6543},"le-source-du-benchmark","Le source du benchmark",[17,6546,6547],{},"Voici de suite :",[65,6549,6550,6556],{},[68,6551,6552],{},[40,6553,6555],{"href":6554},"\u002FProgrammation\u002Fparseur-xml\u002Fxmlparser-bench.7z","les sources de l'application",[68,6557,6558,95],{},[40,6559,6561],{"href":6560},"\u002FProgrammation\u002Fparseur-xml\u002Fbenchmark_100iterations.ods","le résultat du bench",[17,6563,6564],{},"Pour la partie utilisation du Parseur Oracle, il a fallut contourner\nplusieurs petits problèmes. Ceci est la joie des librairies propriétaires\nbien documentées.",[144,6566,6568],{"id":6567},"compilation-avec-le-xdk-9","Compilation avec le XDK 9",[17,6570,6571,6572,6575,6576,6579,6580,95],{},"Lors de la compilation avec le XDK 9, l'application ne dépasse pas le\nstade du ",[20,6573,6574],{},"linkage",". Les méthodes sont pourtant bien dans les ",[20,6577,6578],{},"includes",".\nDe plus les librairies sont bien précisées pour le ",[20,6581,6574],{},[17,6583,6584],{},"La définition faite dans le projet est :",[235,6586,6589],{"className":6587,"code":6588,"language":4607},[4605],"XDKPATH = xdk9\nXDK_LIB = -lxmlg9 -lxml9 -lxsd9\nORA_LIB = -lcore9 -lnls9 -lunls9 -lcore9 -lnls9 -lcore9\nNET_LIB = -lnsl\nLIBS += -L$$XDKPATH\u002Flib $$XDK_LIB $$ORA_LIB $$NET_LIB -lpthread\nINCLUDEPATH += $$XDKPATH\u002Fxdk\u002Finclude\n",[152,6590,6588],{"__ignoreMap":45},[17,6592,6593],{},"A la suite de ça, lors de la phase de compilation, on se retrouve avec\nles messages d'erreurs suivants :",[235,6595,6598],{"className":6596,"code":6597,"language":4607},[4605],"g++ -Wl,-O1 -o xmlparserbenchmark libxml2parser.o expatparser.o xercescppparser.o oracleparser.o qtparser.o scewparser.o tinyparser.o tinyxml.o tinystr.o tinyxmlerror.o tinyxmlparser.o xmlparserbenchmark.o moc_xmlparserbenchmark.o -L\u002Fusr\u002Flib -lxml2 -lexpat -lxerces-c -Lxdk9\u002Flib -lxmlg9 -lxml9 -lxsd9 -lcore9 -lnls9 -lunls9 -lcore9 -lnls9 -lcore9 -lnsl -lpthread -Lscew\u002Fscew -lscew -lQtTest -lQtXml -lQtGui -lQtCore -lpthread\noracleparser.o: In function `parseWithOracleParser(QString const&)':\noracleparser.cpp:(.text+0x82): undefined reference to `XMLParser::xmlinit(unsigned char*, void (*)(void*, unsigned char const*, unsigned int), void*, xmlsaxcb*, void*, unsigned char*)'\noracleparser.cpp:(.text+0xa8): undefined reference to `XMLParser::xmlparse(unsigned char*, unsigned char*, unsigned int)'\noracleparser.cpp:(.text+0x2b4): undefined reference to `XMLParser::getDocumentElement()'\noracleparser.cpp:(.text+0x2ca): undefined reference to `XMLParser::xmlterm()'\n",[152,6599,6597],{"__ignoreMap":45},[17,6601,6602],{},"J'ai alors essayé de recompiler les exemples de démonstrations mais là,\nmême problème ...",[144,6604,6606],{"id":6605},"compilation-avec-le-xdk-10","Compilation avec le XDK 10",[17,6608,6609],{},"Avec cette version du XDK, nous avons le droit à deux problèmes. Le\npremier est une grosse fuite mémoire (si on écrit le programme tel que\ndécrit dans la démo), et à un problème d'initialisation du parseur.",[17,6611,6612],{},"Le code permettant de parser le fichier XML et de générer l'arbre DOM\nressemble à ceci :",[235,6614,6616],{"className":237,"code":6615,"language":239,"meta":45,"style":45},"CXmlCtx * ctxp = 0;\ntry {\n    ctxp = new CXmlCtx();\n} catch( XmlException & e ) {\n    unsigned ecode = e.getCode();\n    QFAIL( qPrintable( QString(\"Failed to initialize XML context, error %1\").arg( ecode ) ) );\n}\n\nFactory\u003CCXmlCtx,xmlnode> * fp = 0;\ntry {\n    fp = new Factory\u003CCXmlCtx,xmlnode>( ctxp );\n} catch( FactoryException & fe ) {\n    unsigned ecode = fe.getCode();\n    QFAIL( qPrintable( QString(\"Failed to create create parser, error %1\").arg( ecode ) ) );\n}\n\nDOMParser\u003CCXmlCtx,xmlnode> * parserp = 0;\ntry {\n    parserp = fp->createDOMParser( DOMParCXml, NULL );\n} catch( FactoryException & fe ) {\n    delete fp;\n    unsigned ecode = fe.getCode();\n    QFAIL( qPrintable( QString(\"Failed to create parser, error %1\").arg( ecode ) ) );\n}\n\nconst char * fname = filename;\nFileSource * isrcp = new FileSource( (oratext*) fname );\ntry {\n    DocumentRef\u003Cxmlnode> * docrefp = parserp->parse( isrcp, FALSE );\n    if( docrefp == NULL ) {\n        QFAIL( qPrintable( QString(\"NULL document\") ) );\n        return;\n    }\n    xmlnode * np = docrefp->getDocumentElement();\n    if( np == NULL ) {\n        QFAIL( qPrintable( QString(\"Empty document\") ) );\n        return;\n    }\n    docrefp->markToDelete();\n    delete docrefp;\n} catch( ParserException & pe ) {\n    delete parserp;\n    delete isrcp;\n    delete fp;\n\n    unsigned ecode = pe.getCode();\n    QFAIL( qPrintable( QString( \"Failed to parse the document, error %1\").arg( ecode ) ) );\n}\n\u002F\u002F    delete parserp;\n\u002F\u002F    delete isrcp;\n\u002F\u002F    delete fp;\n\u002F\u002F    delete ctxp;\n",[152,6617,6618,6634,6642,6656,6673,6693,6722,6726,6730,6753,6759,6785,6799,6816,6839,6843,6847,6869,6875,6899,6911,6919,6935,6958,6962,6966,6984,7009,7015,7044,7059,7080,7086,7090,7112,7125,7144,7150,7154,7166,7173,7187,7194,7201,7207,7211,7228,7251,7255,7260,7265,7270],{"__ignoreMap":45},[243,6619,6620,6623,6625,6628,6630,6632],{"class":245,"line":246},[243,6621,6622],{"class":249},"CXmlCtx ",[243,6624,637],{"class":266},[243,6626,6627],{"class":249}," ctxp ",[243,6629,510],{"class":266},[243,6631,5153],{"class":4455},[243,6633,3390],{"class":249},[243,6635,6636,6639],{"class":245,"line":253},[243,6637,6638],{"class":266},"try",[243,6640,6641],{"class":249}," {\n",[243,6643,6644,6647,6649,6651,6654],{"class":245,"line":260},[243,6645,6646],{"class":249},"    ctxp ",[243,6648,510],{"class":266},[243,6650,645],{"class":266},[243,6652,6653],{"class":276}," CXmlCtx",[243,6655,592],{"class":249},[243,6657,6658,6661,6664,6667,6670],{"class":245,"line":291},[243,6659,6660],{"class":249},"} ",[243,6662,6663],{"class":266},"catch",[243,6665,6666],{"class":249},"( XmlException ",[243,6668,6669],{"class":5314},"&",[243,6671,6672],{"class":249}," e ) {\n",[243,6674,6675,6678,6681,6683,6686,6688,6691],{"class":245,"line":298},[243,6676,6677],{"class":266},"    unsigned",[243,6679,6680],{"class":249}," ecode ",[243,6682,510],{"class":266},[243,6684,6685],{"class":322}," e",[243,6687,95],{"class":249},[243,6689,6690],{"class":276},"getCode",[243,6692,592],{"class":249},[243,6694,6695,6698,6701,6704,6706,6708,6710,6713,6716,6719],{"class":245,"line":304},[243,6696,6697],{"class":276},"    QFAIL",[243,6699,6700],{"class":249},"( ",[243,6702,6703],{"class":276},"qPrintable",[243,6705,6700],{"class":249},[243,6707,85],{"class":276},[243,6709,280],{"class":249},[243,6711,6712],{"class":3364},"\"Failed to initialize XML context, error %1\"",[243,6714,6715],{"class":249},").",[243,6717,6718],{"class":276},"arg",[243,6720,6721],{"class":249},"( ecode ) ) );\n",[243,6723,6724],{"class":245,"line":313},[243,6725,363],{"class":249},[243,6727,6728],{"class":245,"line":319},[243,6729,295],{"emptyLinePlaceholder":294},[243,6731,6732,6735,6737,6740,6742,6744,6747,6749,6751],{"class":245,"line":334},[243,6733,6734],{"class":249},"Factory",[243,6736,267],{"class":266},[243,6738,6739],{"class":249},"CXmlCtx,xmlnode",[243,6741,273],{"class":266},[243,6743,860],{"class":266},[243,6745,6746],{"class":249}," fp ",[243,6748,510],{"class":266},[243,6750,5153],{"class":4455},[243,6752,3390],{"class":249},[243,6754,6755,6757],{"class":245,"line":340},[243,6756,6638],{"class":266},[243,6758,6641],{"class":249},[243,6760,6761,6764,6766,6768,6771,6773,6776,6779,6782],{"class":245,"line":345},[243,6762,6763],{"class":249},"    fp ",[243,6765,510],{"class":266},[243,6767,645],{"class":266},[243,6769,6770],{"class":276}," Factory",[243,6772,267],{"class":249},[243,6774,6775],{"class":322},"CXmlCtx",[243,6777,6778],{"class":249},",",[243,6780,6781],{"class":322},"xmlnode",[243,6783,6784],{"class":249},">( ctxp );\n",[243,6786,6787,6789,6791,6794,6796],{"class":245,"line":351},[243,6788,6660],{"class":249},[243,6790,6663],{"class":266},[243,6792,6793],{"class":249},"( FactoryException ",[243,6795,6669],{"class":5314},[243,6797,6798],{"class":249}," fe ) {\n",[243,6800,6801,6803,6805,6807,6810,6812,6814],{"class":245,"line":360},[243,6802,6677],{"class":266},[243,6804,6680],{"class":249},[243,6806,510],{"class":266},[243,6808,6809],{"class":322}," fe",[243,6811,95],{"class":249},[243,6813,6690],{"class":276},[243,6815,592],{"class":249},[243,6817,6818,6820,6822,6824,6826,6828,6830,6833,6835,6837],{"class":245,"line":918},[243,6819,6697],{"class":276},[243,6821,6700],{"class":249},[243,6823,6703],{"class":276},[243,6825,6700],{"class":249},[243,6827,85],{"class":276},[243,6829,280],{"class":249},[243,6831,6832],{"class":3364},"\"Failed to create create parser, error %1\"",[243,6834,6715],{"class":249},[243,6836,6718],{"class":276},[243,6838,6721],{"class":249},[243,6840,6841],{"class":245,"line":923},[243,6842,363],{"class":249},[243,6844,6845],{"class":245,"line":1108},[243,6846,295],{"emptyLinePlaceholder":294},[243,6848,6849,6852,6854,6856,6858,6860,6863,6865,6867],{"class":245,"line":1123},[243,6850,6851],{"class":249},"DOMParser",[243,6853,267],{"class":266},[243,6855,6739],{"class":249},[243,6857,273],{"class":266},[243,6859,860],{"class":266},[243,6861,6862],{"class":249}," parserp ",[243,6864,510],{"class":266},[243,6866,5153],{"class":4455},[243,6868,3390],{"class":249},[243,6870,6871,6873],{"class":245,"line":1369},[243,6872,6638],{"class":266},[243,6874,6641],{"class":249},[243,6876,6877,6880,6882,6885,6887,6890,6893,6896],{"class":245,"line":1384},[243,6878,6879],{"class":249},"    parserp ",[243,6881,510],{"class":266},[243,6883,6884],{"class":322}," fp",[243,6886,201],{"class":249},[243,6888,6889],{"class":276},"createDOMParser",[243,6891,6892],{"class":249},"( DOMParCXml, ",[243,6894,6895],{"class":4455},"NULL",[243,6897,6898],{"class":249}," );\n",[243,6900,6901,6903,6905,6907,6909],{"class":245,"line":1397},[243,6902,6660],{"class":249},[243,6904,6663],{"class":266},[243,6906,6793],{"class":249},[243,6908,6669],{"class":5314},[243,6910,6798],{"class":249},[243,6912,6913,6916],{"class":245,"line":1402},[243,6914,6915],{"class":266},"    delete",[243,6917,6918],{"class":249}," fp;\n",[243,6920,6921,6923,6925,6927,6929,6931,6933],{"class":245,"line":1407},[243,6922,6677],{"class":266},[243,6924,6680],{"class":249},[243,6926,510],{"class":266},[243,6928,6809],{"class":322},[243,6930,95],{"class":249},[243,6932,6690],{"class":276},[243,6934,592],{"class":249},[243,6936,6937,6939,6941,6943,6945,6947,6949,6952,6954,6956],{"class":245,"line":1415},[243,6938,6697],{"class":276},[243,6940,6700],{"class":249},[243,6942,6703],{"class":276},[243,6944,6700],{"class":249},[243,6946,85],{"class":276},[243,6948,280],{"class":249},[243,6950,6951],{"class":3364},"\"Failed to create parser, error %1\"",[243,6953,6715],{"class":249},[243,6955,6718],{"class":276},[243,6957,6721],{"class":249},[243,6959,6960],{"class":245,"line":1420},[243,6961,363],{"class":249},[243,6963,6964],{"class":245,"line":1425},[243,6965,295],{"emptyLinePlaceholder":294},[243,6967,6968,6971,6974,6976,6979,6981],{"class":245,"line":1442},[243,6969,6970],{"class":266},"const",[243,6972,6973],{"class":266}," char",[243,6975,860],{"class":266},[243,6977,6978],{"class":249}," fname ",[243,6980,510],{"class":266},[243,6982,6983],{"class":249}," filename;\n",[243,6985,6986,6989,6991,6994,6996,6998,7001,7004,7006],{"class":245,"line":1447},[243,6987,6988],{"class":249},"FileSource ",[243,6990,637],{"class":266},[243,6992,6993],{"class":249}," isrcp ",[243,6995,510],{"class":266},[243,6997,645],{"class":266},[243,6999,7000],{"class":276}," FileSource",[243,7002,7003],{"class":249},"( (oratext",[243,7005,637],{"class":266},[243,7007,7008],{"class":249},") fname );\n",[243,7010,7011,7013],{"class":245,"line":1469},[243,7012,6638],{"class":266},[243,7014,6641],{"class":249},[243,7016,7017,7020,7022,7024,7026,7028,7031,7033,7036,7038,7041],{"class":245,"line":1476},[243,7018,7019],{"class":249},"    DocumentRef",[243,7021,267],{"class":266},[243,7023,6781],{"class":249},[243,7025,273],{"class":266},[243,7027,860],{"class":266},[243,7029,7030],{"class":249}," docrefp ",[243,7032,510],{"class":266},[243,7034,7035],{"class":322}," parserp",[243,7037,201],{"class":249},[243,7039,7040],{"class":276},"parse",[243,7042,7043],{"class":249},"( isrcp, FALSE );\n",[243,7045,7046,7048,7051,7053,7056],{"class":245,"line":1481},[243,7047,307],{"class":266},[243,7049,7050],{"class":249},"( docrefp ",[243,7052,3419],{"class":266},[243,7054,7055],{"class":4455}," NULL",[243,7057,7058],{"class":249}," ) {\n",[243,7060,7061,7064,7066,7068,7070,7072,7074,7077],{"class":245,"line":1506},[243,7062,7063],{"class":276},"        QFAIL",[243,7065,6700],{"class":249},[243,7067,6703],{"class":276},[243,7069,6700],{"class":249},[243,7071,85],{"class":276},[243,7073,280],{"class":249},[243,7075,7076],{"class":3364},"\"NULL document\"",[243,7078,7079],{"class":249},") ) );\n",[243,7081,7082,7084],{"class":245,"line":1522},[243,7083,1069],{"class":266},[243,7085,3390],{"class":249},[243,7087,7088],{"class":245,"line":1527},[243,7089,337],{"class":249},[243,7091,7092,7095,7097,7100,7102,7105,7107,7110],{"class":245,"line":1541},[243,7093,7094],{"class":249},"    xmlnode ",[243,7096,637],{"class":266},[243,7098,7099],{"class":249}," np ",[243,7101,510],{"class":266},[243,7103,7104],{"class":322}," docrefp",[243,7106,201],{"class":249},[243,7108,7109],{"class":276},"getDocumentElement",[243,7111,592],{"class":249},[243,7113,7114,7116,7119,7121,7123],{"class":245,"line":4213},[243,7115,307],{"class":266},[243,7117,7118],{"class":249},"( np ",[243,7120,3419],{"class":266},[243,7122,7055],{"class":4455},[243,7124,7058],{"class":249},[243,7126,7127,7129,7131,7133,7135,7137,7139,7142],{"class":245,"line":4219},[243,7128,7063],{"class":276},[243,7130,6700],{"class":249},[243,7132,6703],{"class":276},[243,7134,6700],{"class":249},[243,7136,85],{"class":276},[243,7138,280],{"class":249},[243,7140,7141],{"class":3364},"\"Empty document\"",[243,7143,7079],{"class":249},[243,7145,7146,7148],{"class":245,"line":4224},[243,7147,1069],{"class":266},[243,7149,3390],{"class":249},[243,7151,7152],{"class":245,"line":4229},[243,7153,337],{"class":249},[243,7155,7156,7159,7161,7164],{"class":245,"line":4234},[243,7157,7158],{"class":322},"    docrefp",[243,7160,201],{"class":249},[243,7162,7163],{"class":276},"markToDelete",[243,7165,592],{"class":249},[243,7167,7168,7170],{"class":245,"line":4240},[243,7169,6915],{"class":266},[243,7171,7172],{"class":249}," docrefp;\n",[243,7174,7175,7177,7179,7182,7184],{"class":245,"line":4246},[243,7176,6660],{"class":249},[243,7178,6663],{"class":266},[243,7180,7181],{"class":249},"( ParserException ",[243,7183,6669],{"class":5314},[243,7185,7186],{"class":249}," pe ) {\n",[243,7188,7189,7191],{"class":245,"line":4252},[243,7190,6915],{"class":266},[243,7192,7193],{"class":249}," parserp;\n",[243,7195,7196,7198],{"class":245,"line":4258},[243,7197,6915],{"class":266},[243,7199,7200],{"class":249}," isrcp;\n",[243,7202,7203,7205],{"class":245,"line":4264},[243,7204,6915],{"class":266},[243,7206,6918],{"class":249},[243,7208,7209],{"class":245,"line":4320},[243,7210,295],{"emptyLinePlaceholder":294},[243,7212,7213,7215,7217,7219,7222,7224,7226],{"class":245,"line":4377},[243,7214,6677],{"class":266},[243,7216,6680],{"class":249},[243,7218,510],{"class":266},[243,7220,7221],{"class":322}," pe",[243,7223,95],{"class":249},[243,7225,6690],{"class":276},[243,7227,592],{"class":249},[243,7229,7230,7232,7234,7236,7238,7240,7242,7245,7247,7249],{"class":245,"line":4382},[243,7231,6697],{"class":276},[243,7233,6700],{"class":249},[243,7235,6703],{"class":276},[243,7237,6700],{"class":249},[243,7239,85],{"class":276},[243,7241,6700],{"class":249},[243,7243,7244],{"class":3364},"\"Failed to parse the document, error %1\"",[243,7246,6715],{"class":249},[243,7248,6718],{"class":276},[243,7250,6721],{"class":249},[243,7252,7253],{"class":245,"line":4387},[243,7254,363],{"class":249},[243,7256,7257],{"class":245,"line":4392},[243,7258,7259],{"class":256},"\u002F\u002F    delete parserp;\n",[243,7261,7262],{"class":245,"line":4397},[243,7263,7264],{"class":256},"\u002F\u002F    delete isrcp;\n",[243,7266,7267],{"class":245,"line":4411},[243,7268,7269],{"class":256},"\u002F\u002F    delete fp;\n",[243,7271,7272],{"class":245,"line":4416},[243,7273,7274],{"class":256},"\u002F\u002F    delete ctxp;\n",[17,7276,7277,7278,7280,7281,7283,7284,95],{},"Le premier problème se situe lors de la suppression du contexte\n(dernière ligne, en commentaire). Si cette ligne est exécutée, alors\nnous avons une grosse erreur de segmentation. J'ai le problème, quels\nque soient les ",[152,7279,2809],{}," que je fais avant.Même en faisant le maximum de\n",[152,7282,2809],{}," (soit parserp, isrcp, fp), le fait de ne pas supprimer le\ncontext (ctxp), fait qu'au bout de plusieurs itérations, nous avons une\nbonne fuite mémoire",[37,7285,7286],{},[40,7287,94],{"href":91,"ariaDescribedBy":7288,"dataFootnoteRef":45,"id":93},[44],[17,7290,7291],{},"Vient ensuite le second problème, celui des erreurs d'intialisation. Si\nle parseur est lancé plusieurs fois de suite, alors l'application\naffiche les erreurs suivantes à l'écran :",[235,7293,7296],{"className":7294,"code":7295,"language":4607},[4605],"LPX-00202: Message 202 not found; No message file for product=XDK, facility=LPX\nFAIL!  : XmlParserBenchmark::oracleParser(file250k.xml) Failed to parse the document, error 202\n    Loc: [oracleparser.cpp(73)]\n",[152,7297,7295],{"__ignoreMap":45},[17,7299,7300],{},"Aucune explication sur le pourquoi. Parfois ça marche, parfois non...\nPour contourner le problème, j'ai forké le parseur pour l'exécuter isolé\ndu reste.",[235,7302,7305],{"className":7303,"code":7304,"language":1677,"meta":45,"style":45},"language-c shiki shiki-themes one-dark-pro","pid_t pid = fork();\nif( pid > 0 ) {\n    waitpid( pid, (int*)0, 0 );\n} else if( pid == 0 ) {\n    if( ! filename.isEmpty() )\n        parse( qPrintable( filename ) );\n    exit( 0 );\n} else {\n    QFAIL( \"Cannot fork\" );\n}\n",[152,7306,7307,7322,7335,7358,7376,7396,7408,7419,7427,7438],{"__ignoreMap":45},[243,7308,7309,7312,7315,7317,7320],{"class":245,"line":246},[243,7310,7311],{"class":266},"pid_t",[243,7313,7314],{"class":249}," pid ",[243,7316,510],{"class":266},[243,7318,7319],{"class":276}," fork",[243,7321,592],{"class":249},[243,7323,7324,7326,7329,7331,7333],{"class":245,"line":253},[243,7325,574],{"class":266},[243,7327,7328],{"class":249},"( pid ",[243,7330,273],{"class":266},[243,7332,5153],{"class":4455},[243,7334,7058],{"class":249},[243,7336,7337,7340,7343,7346,7349,7352,7354,7356],{"class":245,"line":260},[243,7338,7339],{"class":276},"    waitpid",[243,7341,7342],{"class":249},"( pid, (",[243,7344,7345],{"class":266},"int*",[243,7347,7348],{"class":249},")",[243,7350,7351],{"class":4455},"0",[243,7353,4624],{"class":249},[243,7355,7351],{"class":4455},[243,7357,6898],{"class":249},[243,7359,7360,7362,7365,7368,7370,7372,7374],{"class":245,"line":291},[243,7361,6660],{"class":249},[243,7363,7364],{"class":266},"else",[243,7366,7367],{"class":266}," if",[243,7369,7328],{"class":249},[243,7371,3419],{"class":266},[243,7373,5153],{"class":4455},[243,7375,7058],{"class":249},[243,7377,7378,7380,7382,7385,7388,7390,7393],{"class":245,"line":298},[243,7379,307],{"class":266},[243,7381,6700],{"class":249},[243,7383,7384],{"class":5314},"!",[243,7386,7387],{"class":322}," filename",[243,7389,95],{"class":249},[243,7391,7392],{"class":276},"isEmpty",[243,7394,7395],{"class":249},"() )\n",[243,7397,7398,7401,7403,7405],{"class":245,"line":304},[243,7399,7400],{"class":276},"        parse",[243,7402,6700],{"class":249},[243,7404,6703],{"class":276},[243,7406,7407],{"class":249},"( filename ) );\n",[243,7409,7410,7413,7415,7417],{"class":245,"line":313},[243,7411,7412],{"class":276},"    exit",[243,7414,6700],{"class":249},[243,7416,7351],{"class":4455},[243,7418,6898],{"class":249},[243,7420,7421,7423,7425],{"class":245,"line":319},[243,7422,6660],{"class":249},[243,7424,7364],{"class":266},[243,7426,6641],{"class":249},[243,7428,7429,7431,7433,7436],{"class":245,"line":334},[243,7430,6697],{"class":276},[243,7432,6700],{"class":249},[243,7434,7435],{"class":3364},"\"Cannot fork\"",[243,7437,6898],{"class":249},[243,7439,7440],{"class":245,"line":340},[243,7441,363],{"class":249},[3070,7443,7445,7448],{"className":7444,"dataFootnotes":45},[3073],[3075,7446,3079],{"className":7447,"id":44},[3078],[3081,7449,7450,7456],{},[68,7451,7452,7453],{"id":3085},"Ces tests ont été réalisé dans un chroot 32-bits allant à 2,4GHz. Les temps sont une moyenne sur 100 itérations ",[40,7454,3093],{"href":3089,"ariaLabel":3090,"className":7455,"dataFootnoteBackref":45},[3092],[68,7457,7458,7459],{"id":3096},"Si quelqu'un a déjà utilisé ce parseur, et qu'il sait comment il fonctionne, il peut m'écrire ",[40,7460,3093],{"href":3100,"ariaLabel":3101,"className":7461,"dataFootnoteBackref":45},[3092],[3224,7463,7464],{},"html pre.shiki code .sn6KH, html code.shiki .sn6KH{--shiki-default:#ABB2BF}html pre.shiki code .seHd6, html code.shiki .seHd6{--shiki-default:#C678DD}html pre.shiki code .sVC51, html code.shiki .sVC51{--shiki-default:#D19A66}html pre.shiki code .sVbv2, html code.shiki .sVbv2{--shiki-default:#61AFEF}html pre.shiki code .sjrmR, html code.shiki .sjrmR{--shiki-default:#56B6C2}html pre.shiki code .sU0A5, html code.shiki .sU0A5{--shiki-default:#E5C07B}html pre.shiki code .subq3, html code.shiki .subq3{--shiki-default:#98C379}html pre.shiki code .sV9Aq, html code.shiki .sV9Aq{--shiki-default:#7F848E;--shiki-default-font-style:italic}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":45,"searchDepth":253,"depth":253,"links":7466},[7467,7468,7469,7470],{"id":6305,"depth":260,"text":6306},{"id":6321,"depth":260,"text":6322},{"id":6543,"depth":260,"text":6544},{"id":44,"depth":253,"text":3079},"2009-05-31",{"type":9,"value":7473},[7474,7476],[17,7475,6292],{},[17,7477,6295,7478,6299],{},[20,7479,6298],{},{},"\u002Fpost\u002Fparseur-xml",{"title":6287,"description":6292},"parseur-xml","posts\u002FProgrammation\u002F2009-05-31-parseur-xml",[3319,3320,7486],"xml","G7dHisiUAKK_MNKBFUElPa66LJWw54bB5Z9U4-7H4Ck",1777849587711]