Aller au contenu

Optimisations inutiles?


Messages recommandés

Bonjour,

Juste un post pour avoir un peu l'avis d'autres développeurs.

Il y a longtemps, je faisais attention à utiliser les bons types de variables (short/long/int/float). Maintenant, dans la plupart des programmes que je croise, à part le int lié à la plate-forme, tout est en long et les nombres en décimaux.

Avant, on faisait attention dans les bases de données au type de la clé, au "collation", au format char/varchar/nvarchar... Maintenant, je vois des tables indexées sur des nvarchar contenant un code 4 lettres sans string collation...

Même si ces optimisations n'ont pas un impact significatif sur les perfs au moment du dev, dans 4 ans, quand on va faire une requête avec un join sur un nvarchar sans collation, on va quand même mettre une pression sur le CPU et la RAM (déjà vécu avec un générateur de BDD qui générait un GUID mais le faisait stocker sur un char(36)).

Qu'en pensez-vous? Est-ce que vous vous dites "de la RAM, du CPU, de la BP disque et de la bière il y en aura toujours", ou "plus c'est optimisé, plus je peux en mettre sur le même serveur"?

De même, pour les échanges on utilise XML ou JSON, mais leur efficacité face à une sérialisation binaire est ridicule, ça mange de la BP réseau, de la RAM et du CPU pour le décodage en permanence. C'est anti-green IT tout cela, non?

Lien vers le commentaire
Partager sur d’autres sites

Je suis un jeune développeur et je t'avoue que les optimisations dont tu parles, on ne me les a jamais inculquées ni demandé de faire attention. Notamment sur tes exemples de types en BDD. À part un "il est trop long ou trop court ton nvarchar", les optimisations se font rarement là dessus. Là seule erreur que j'ai vue c'est des entiers stockés en varchar et la conversion ralentissait tout.

Pour ce qui est du JSON ou XML, effectivement c'est moins efficace, mais je préfère que les données qui transitent restent humainement compréhensibles.

Lien vers le commentaire
Partager sur d’autres sites

Perso, je suis peut-être aussi de la vieille école, mais je fais attention au typage. Pas besoin de déclarer un long si je n'en ai pas besoin.

Après, en dehors du stockage BDD, il vaut parfois mieux utiliser un Int32 ou Int64 qu'un Byte car le traitement CPU est optimisé pour ce genre d'entiers.

Créer des index sur des chaînes, c'est rarement intelligent, mais normalement, ça ne pose pas de problème sur des chaînes courtes avec peu de valeurs différentes. Bref, ça va vraiment dépendre de ce que va contenir le champ.

Quand au XML et au JSON, pour le premier, c'est à bannir, beaucoup trop verbeux et peu lisible. Pour le second, je n'utilise que ça, c'est très rapide à traiter et si on veut le stocker ou le faire transiter sur un réseau, une compression LZ est rapide et efficace. De plus, des tas de bibliothèques sont optimisées pour le traiter et c'est facile à analyser pour déboguer.

Lien vers le commentaire
Partager sur d’autres sites

Je n'ai toujours utilisé que 2 typages dans mes BDD (ça fait 35 ans) : varchar et decimal (un peu de Blob aussi).

Ces deux formats suffisent et sont correctement traités quelques soient les langages, et les connecteurs.

Pour les langages, j'en ai rencontré plusieurs qui n'avaient que 3 types : string, number, boolean Aussi bien des vieux (BASIC) que des récents (SQL-Windows), preuve qu'on a pas besoin des milliers de raffinements disponibles (MS est très for la-dessus).

Et on a des machines débordant de ressources a des prix dérisoires, alors l'optimisation je m'assois dessus tant que mes traitements répondent au quart de tour. Une bonne requete SQL y'a que çca de vrai.

Lien vers le commentaire
Partager sur d’autres sites

Tu ne dois pas bosser sur des grandes quantités de données alors 😉

Dans ma boîte actuelle (et pour la première fois), l'optimisation est le mot d'ordre. Que des requêtes simples avec des retours limités (celui qui fait un SELECT * meurt dans d'atroces souffrances !).

Ensuite, on traite en mémoire haute en évitant de charger la pile (utilisation d'interface plutôt que d'instanciation de classes), mise ne place de caches locaux pour n’appeler la base que si nécessaire, traitements en parallèle dès que possible (sans en abuser), etc.

Après, je bosse dans la paye, et faut brasser une très grande quantité de données et quand on voit les serveurs sous-dimensionnés des clients, l'optimisation est vitale !

Lien vers le commentaire
Partager sur d’autres sites

Il y a 11 heures, Bamaury a écrit :

 À part un "il est trop long ou trop court ton nvarchar", les optimisations se font rarement là dessus. Là seule erreur que j'ai vue c'est des entiers stockés en varchar et la conversion ralentissait tout.

La taille importe peu... Je connais bien SQL Server, en gros, tu peux faire un nvarchar(MAX) au moment d'enregistrer la donnée:

* Si la valeur est courte, elle passe dans la ligne de données sans même indiquer la taille (8 octets maxi donc 4 char). Sinon SQL server le met à la suite avec une indication de la taille. Si la ligne déborde (> 8ko), la valeur est stockée en tant que référence à une autre ligne de stockage long et la valeur est stockée hors d ela ligne (donc si tu fais un select * , il devra lire au moins 2 lignes qui ne sont pas stockées au même endroit -> perte de perfs).

Sous SQL server, tout est lu par défaut par tranche de 8ko: plus tu en mets en 8ko, et plus il lit de tranches de 8ko qui sont stockées à la suite sur le disque, plus ça vite.

Globalement, les moteurs se ressemblent sur ce point là.

Il y a 7 heures, Aloyse57 a écrit :

Je n'ai toujours utilisé que 2 typages dans mes BDD (ça fait 35 ans) : varchar et decimal (un peu de Blob aussi).

Le décimal a l'avantage d'être "naturellement compris" par le développeur, contrairement à la virgule flottante. Le varchar est maintenant souvent dépassé et nécessite un nvarchar. Je comprends le si ça marche suffisamment bien, pourquoi changer? Mais dans un cadre de mutualisation des ressources, suppression de serveur, réduction des licences donc des coeurs, j'ai un doute avec des applis dont les SELECt déclenchent systématiquement un table scan...

 

Il y a 7 heures, Edtech a écrit :

Que des requêtes simples avec des retours limités (celui qui fait un SELECT * meurt dans d'atroces souffrances !).

 quand on voit les serveurs sous-dimensionnés des clients, l'optimisation est vitale !

Normal de crucifier un SELECT *. Ceci dit, j'aimerais crucifier aussi les gars qui ont décidé que dans une clause SELECT, la liste des colonnes serait avant le FROM...

Quand aux serveurs, s'ils suffisent, ils ne sont pas sous-dimensionnés 🙂 

Bon, je compatis, je subis les logiciels de paye en tant qu'utilisateur, et tes oreilles doivent siffler 🙂 . La paye et la compta, ce sont les 2 domaines les plus gourmands dans mes expériences et ils sont tous les 2 critiques.

 

 

Au final donc, peu d'intérêt pour les optimisations sauf cas particulier. Et à ce moment, il faut sortir toute l'artillerie...

Merci! Je ne vais plus insister dessus dans mes "formations"

Lien vers le commentaire
Partager sur d’autres sites

Il y a 23 heures, Edtech a écrit :

Tu ne dois pas bosser sur des grandes quantités de données alors 😉

...
Après, je bosse dans la paye, et faut brasser une très grande quantité de données et quand on voit les serveurs sous-dimensionnés des clients, l'optimisation est vitale !

ERP de quelques centaines de tables qui ont 20ans de données dedans (certaines ont des millions de records) . Je sors aussi la paie de 1000 employés par semaine (on est payé à la semaine ici), donc 52x historique au lieu de 12x.

Et le tout est dans un SQL Server 2003, l'ERP sur un W2K (clients sur W10x64).

Je ne sais pas si tu trouves ça gros ou petit, mais je trouve ça pas mal comme BDD pour détecter les requêtes maladroites.😅

Lien vers le commentaire
Partager sur d’autres sites

Tiens, c'est pas courant à la semaine. 1000 payes, ça va, c'est encore léger. Et puis, tu utilises SQL Server, nous Interbase 😅 (pas de réflexions sur le sujet, merci 😁).

Après, ça dépend surtout du turnover. On a des clients qui renouvellent 75% du personnel par mois (énormément d'intérim et de CDD), avec donc pour un même salarié parfois 4 ou 5 contrats par mois ! Tu fais ça sur 5000 payes, ça rame sévère (on est à 1,2s la paye environ, on veut diviser ce temps par 10).

Lien vers le commentaire
Partager sur d’autres sites

  • 4 semaines après...
On 10/10/2019 at 14:58, Edtech a écrit :

Tiens, c'est pas courant à la semaine. 1000 payes, ça va, c'est encore léger. Et puis, tu utilises SQL Server, nous Interbase 😅 (pas de réflexions sur le sujet, merci 😁).

... ça rame sévère (on est à 1,2s la paye environ, on veut diviser ce temps par 10).

De mémoire, interbase n'a pas de locks et fait une grosse pression disque si on lit/écrit dans une même transaction de nombreuses lignes (et les count doivent être fait avant toute écriture). Et plus tu parallélises, plus il est lourd.

Si le problème c'est l'écriture disque (diagnosticable via l'affichage de la file d'attente d'écriture dans les compteurs de perf Windows), on optimise interbase avec un stockage très rapide en écriture, donc en raid 10 par exemple ou un raid via une carte contrôleur avec une cache RAM importante sauvegardée par pile (sans cela la plupart du temps le cache n'est qu'en lecture).

Avant pour optimiser interbase il était même conseillé d'activer le cache en écriture au niveau du système... même maintenant je trouve que c'est pour les joueurs.

La paye c'est toujours lourd à optimiser. C'est avec un serveur paye que j'ai commencé à aller dans le paramétrage des max dop et autres sous SQL server.

Lien vers le commentaire
Partager sur d’autres sites

  • 3 mois après...

J’ai développé dans pas mal de langages (java, android, C#, python, bash, …) avant de rester sur le C++ pendant un moment. Principalement pour le fait que c’était LE langage pour créer des jeux vidéos (c’était avant Unity) et aussi il était cross platform (avec beaucoup de travail pour le rendre cross-platform) et il avait des performances (très) bonnes. J’ai adoré apprendre plein de choses avec ce langage, mais le gros probème, cette amélioration de perf, ça venait avec une complexité de fou. Déjà, gérer sa mémoire avec ses pointeurs, tout de suite tu rajoutes une charge mentale sur ton design. Et même en réfléchissant bien, il suffisait que tu oubliais un cas moisi, et hop tu te retrouvais avec de la mémoire non libérée, même avec des std::shared_ptr, un double delete sur une zone mémoire. Parce que, que tu le veuilles ou non, tu arriveras à un moment sur un programme pas écrit par toi, trop gros pour comprendre exactement où les choses sont allouées/désallouées, si c’est sur le même thread ou non, etc.

Et là, tu commences à perdre des cheveux. Oui, tu peux être optimisé, mais ça vient à un tel coût en développement et en maintenance pour bien le faire qu’après, tu abandonnes, perd la motivation, et fait de la merde, quand ce n’est pas ton boss direct qui te dit qu’on n’a pas le temps pour faire ça.

Depuis, j’ai découvert le Go, et ça a de bonne performances mais ça te facilite énormément de choses sur la gestion mémoire (il y a un bon garbage collector) et le multi threading (il possède des concepts natifs permettant de faire de la programmation concurrente beaucoup plus facilement que beaucoup de langages). Go est souvent utilisé pour remplacer des composants plus gourmands dans des startups qui grossissent. La startup a commencé à avoir des millions d’utilisateurs, et leur (micro)service en PHP, Java, Python, Ruby ne tient plus la charge ou coûte trop cher en serveur cloud, et du coup ils passent au Go pour rendre ça plus gérable.

Mais ce qui est encore plus important que les performances sur le Go, c’est que les créateurs du langage l’ont rendu puissant côté machine, mais ont essayé de le garder simple côté humain. Ils promeuvent beaucoup la lisibilité ou la maintenabilité d’un programme. Du coup, par défaut, le compilateur Go va t’optimiser un max de trucs, pour pas que tu aies à le faire (c’est aussi le cas de compilateurs comme GCC et CLANG en passant, ça optimise à fond). Mais aussi, ils te fournissent un max d’outils pour profiler en live ton application sans impacter trop les perfs (je crois que pprof doit bouffer 1% de perf quand il est en profiling actif). Du coup, la mantra, c’est Fait le marcher (compile + run ok), fait le bien (refactor, redesign), rend le rapide (optimise)

Et franchement, ça marche bien. Tu fais un code minimal qui marche, tu le redesignes pour qu’il soit lisible/compréhensible (par qqn d’autres, ou toi plus tard :p) et après, tu mesures/benchmark/profile et tu optimises là où les outils te disent qu’il y a un gain possible à prendre.

Je ne compte plus le nombre de fois où j’ai commencé à optimiser un endroit en étant persuadé que c’était là le problème, et en fait, pas du tout, avec les optim compilateurs, le goulot d’étranglement était ailleurs. Avec Go, j’optimise que quand j’en ai besoin et que si ça ne se fait pas avec un coût trop gros sur la maintenance. Mais clairement, si je pouvais remplacer par Go + du graphisme natif (opengl ou autre) toutes ces applis électrons qui bouffent 300 Mo min de ram + CPU juste pour afficher un chat, ça ferait plaisir à mon laptop avec ses 8Go de ram.

Lien vers le commentaire
Partager sur d’autres sites

Archivé

Ce sujet est désormais archivé et ne peut plus recevoir de nouvelles réponses.

×
×
  • Créer...