n_e a écrit 29 commentaires

  • [^] # Re: ton llm n'aime pas mon derche?

    Posté par  . En réponse au journal Je vous présente mon projet entièrement généré par IA. Évalué à 3 (+7/-5).

    Je ne comprends pas bien le but de ton commentaire : j'ai dit dès la première phrase du journal que le but du projet était de tester l'IA, et donc "l'apprentissage", que tu sembles remettre en question c'est ça. La moitié du journal fait part de mes conclusions et donc de ce que j'ai appris.

    Quand à la conception que tu prétends que j'ai "délégué à mon LLM" (j'explique là aussi dans le journal comment je l'ai faite, et mets un lien vers la spec), voilà quelques infos :

    • "pourquoi tout indexer plutôt que bien cibler les bons contenus" : j'ai choisi par souci de simplicité et vu que c'était de toute façon une fonctionnalité indispensable. L'indexation incrémentale peut être ajoutée dans un 2e temps. Si c'est la charge sur linuxfr qui t'inquiète, le script n'est pas dans un cronjob et n'a été exécuté qu'une fois.

    • "Pourquoi Elastic opencore alors qu'il y a opensearch vraiment libre" : parce que je préfère ne pas utiliser un projet géré par Amazon

  • [^] # Re: Journal arrivé après tant d’autres

    Posté par  . En réponse au journal Je vous présente mon projet entièrement généré par IA. Évalué à 3 (+4/-2).

    Peut-être aurait‐il eu une note positive si ton moteur de recherche est pleinement fonctionnel

    Bah en fait il est pleinement fonctionnel (en tout cas davantage que le moteur actuel), je ne comprends pas pourquoi tu dis ça.

    Il est testable en deux clics, j'ai expliqué dans le journal ma démarche pour la correction des bugs, et le premier commentaire sous le journal dit qu'il est "infiniment supérieur" au moteur précédent.

  • [^] # Re: Journal écrit

    Posté par  . En réponse au journal Je vous présente mon projet entièrement généré par IA. Évalué à 1 (+2/-2).

    Pour moi, mais je peux me tromper, l’erreur que j’ai faite est l’angle de mon journal (et surtout le titre) .

    Si j’avais simplement mis un lien et une brève présentation vers un meilleur outil de recherche pour linuxfr je suis prêt à parier que ça aurait été largement plussé

  • [^] # Re: ton llm n'aime pas mon derche?

    Posté par  . En réponse au journal Je vous présente mon projet entièrement généré par IA. Évalué à 0 (+3/-4).

    J'ajouterais qu'en plus, si j'ai bien lu le code, mon test a davantage de fonctionnalités : indexation du site complet (alors que derche n'utilise que le flux atom), filtrage selon plusieurs critères.

  • [^] # Re: C'est un bon début

    Posté par  . En réponse au journal Je vous présente mon projet entièrement généré par IA. Évalué à 0 (+4/-5).

    Merci pour tes retours, j'ai déjà fait les dernières modifs. avec Sol, et il y a clairement du progrès par rapport à Luna (il teste après avoir codé par défaut, il est plus persistant dans l'analyse des bugs).

  • [^] # Re: Journal écrit

    Posté par  . En réponse au journal Je vous présente mon projet entièrement généré par IA. Évalué à 5 (+7/-3).

    Est-ce pour ça qu'il est ainsi noté ?

    Je pense surtout que la blague du titre (pastiche des journaux de spam supprimés) est tombée à plat et que les gens ont moinssé sans lire le contenu.

    Concernant les problématiques économique, sociologiques et environnementales, je suis complètement d'accord que c'est important. En ce qui concerne le journal je ne peux pas parler de tout et me suis concentré sur mon retour d'expérience. A titre personnel j'essaie de faire un usage raisonnable des tokens, et idéalement utiliser des modèles auto-hébergés, mais ce n'est pas encore ça niveau prix et disponibilité du matériel…

  • [^] # Re: Here-doc et pipe sur les deux derniers exemples

    Posté par  . En réponse au journal Écrire du JSON dans un script bash. Évalué à 1 (+0/-0).

    Merci !

  • [^] # Re: Bash

    Posté par  . En réponse au journal Écrire du JSON dans un script bash. Évalué à 10 (+11/-0).

    Autant je suis d'accord que bash est inadapté à des scripts trop compliqués et qu'il a beaucoup de footguns, autant il a deux avantages très importants :

    • Il est installé partout
    • Il permet de passer très facilement de commandes lancées manuellement dans un terminal à un script

    Pour les footguns, shellcheck est un très bon linter et permet d'identifier facilement la plupart des commentaires.

    Quant à la remarque "Bash est hasbeen", je ne sais pas quoi y répondre vu que dans la foulée tu proposes d'utiliser Perl.

  • [^] # Re: Répertoire d'ouvertures ?

    Posté par  . En réponse au journal Ecrire un moteur d'échecs surhumain - Partie 2. Évalué à 3 (+2/-0).

    J'ai ajouté une licence (GPLv3)

  • [^] # Re: Répertoire d'ouvertures ?

    Posté par  . En réponse au journal Ecrire un moteur d'échecs surhumain - Partie 2. Évalué à 2 (+1/-0).

    Je compte qu'il devienne suffisamment fort suffisamment tôt pour ne pas avoir besoin de répertoire d'ouvertures. En plus je trouve intéressant de le laisser lui-même trouver les ouvertures et voir ce qu'il découvre.

    Aussi, les compétitions d'ordinateurs ont des ouvertures imposées (parce que les ordis les plus forts font toujours nulle en partant de la position initiale - on fait donc des matchs aller-retour à partir d'une position imposée).

  • [^] # Re: Roque et FRC

    Posté par  . En réponse au journal Ecrire un moteur d'échecs surhumain - Partie 2. Évalué à 1 (+0/-0).

    Envisages-tu que ton moteur soit capable de jouer des parties FRC (ou Chess960) voire même DFRC (ou FRD) ?

    Oui et non. Non parce que à titre personnel je n'y ai jamais joué et ça ne m'intéresse pas (je trouve déjà les échecs normaux suffisamment difficiles). Oui, au sens que j'y ai pensé et que si je change d'avis ça ne sera pas trop compliqué à changer (du moins pour la partie règles).

  • [^] # Re: Toute la colonne, pas les autres

    Posté par  . En réponse au journal Rechercher des fichiers CSV (sans IA). Évalué à 3 (+2/-0).

    Si le filtre doit parcourir la colonne entière, le temps reste linéaire.

    La complexité algorithmique reste linéaire. Par contre, et je trouve ça fascinant, c'est que la lecture est tellement rapide (grâce à la localité des données et le filtrage qui est souvent fait avec des instructions SIMD), que bien que la complexité algorithmique soit naze, ça reste rapide.

    D'ailleurs les bases de données colonne ne supportent pas (du moins les plus courantes comme clickhouse, duckdb, bigquery, etc.) les index BTree.

    Il y a cependant des optimisations, mais qui la plupart du temps n'affectent pas la complexité algorithmique (skip indexes, tri selon la clé primaire, parallélisation).

  • [^] # Re: Stockfish est les deux

    Posté par  . En réponse au journal Ecrire un moteur d'échecs surhumain - Partie 1. Évalué à 6 (+5/-0).

    Je n'ai effectivement pas en tête d'amélioration "utile" datant disons de ces cinq dernières années, par contre si on compare à il y a 20 ans c'est la révolution.

    Par exemple en ce moment je suis en train d'apprendre une nouvelle ouverture, et je le fais uniquement avec une base de parties et Stockfish. Il y a 20 ans j'aurais dû acheter un livre, qui n'aurait peut-être pas existé ou traité les lignes qui m'intéressent, et qui aurait été probablement faux.

    Quant aux explications des coups joués, effectivement c'est quelque chose qui n'existe pas vraiment (si ce n'est la fonctionnalité de chess.com qui a un gros manque de pertinence), mais il y a pas mal de techniques pour comprendre un coup de l'ordi :

    • faire passer le tour plusieurs fois à l'adversaire et regarder comment l'ordi progresse en l'absence de défense

    • jouer des coups logiques contre l'ordi et regarder comment il punit

    • jouer la même suite de coups après le coup de l'ordi et le coup qui nous semble logique, et comparer

    Il faut aussi ne pas hésiter à rejeter un coup de l'ordi s'il ne parait pas approprié (par ex. il propose souvent un mauvais coup positionnel mais qui marche grâce à des complications tactiques incompréhensibles, alors qu'un coup logique est OK)

  • [^] # Re: perft avant cutechess

    Posté par  . En réponse au journal Ecrire un moteur d'échecs surhumain - Partie 1. Évalué à 2 (+1/-0).

    Tout à fait ! Je ne l'ai pas précisé dans le journal, mais effectivement ça fera partie de la première étape de m'assurer qu'il n'y a pas de bugs dans le générateur de coups.

  • [^] # Re: Stockfish est les deux

    Posté par  . En réponse au journal Ecrire un moteur d'échecs surhumain - Partie 1. Évalué à 4 (+3/-0).

    Stockfish est purement un moteur classique, même s'il utilise aujourd'hui un réseau neuronal pour évaluer les positions : il explore énormément de branches avec un algorithme minimax, et évalue les positions rapidement avec une fonction d'évaluation rapide et rudimentaire (comparé aux descendants d'AlphaZero, pas à deepblue). Les optimisations très pointues pour limiter le nombre de branches explorées et donc augmenter la profondeur sont également typiques des architectures classiques, et on les retrouve que le moteur utilise une évaluation NNUE (par réseau neuronal) ou HCE (écrite à la main).

    Je pense que ce qui illustre le mieux la différence entre archi classique et archi "type AlphaZero", est que stockfish explore des millions de noeuds par seconde, alors que le moteur Maia (basé sur LeelaChess0) joue à un niveau correct (jusqu'à 1900 ELO) en utilisant juste la fonction d'évaluation et sans faire de recherche.

  • [^] # Re: Ce que tu me dis pas...

    Posté par  . En réponse au journal Ecrire un moteur d'échecs surhumain - Partie 1. Évalué à 3 (+2/-0).

    c'est comment tu mesuresde façon impartiale que le niveau de jeu a augmenté ou pas par rapport au commit précédent

    Effectivement, en faisant jouer l'ordi contre lui-même, idéalement en cadences rapides pour que ça ne prenne pas trop de temps. Et en utilisant un test statistique pertinent pour ne pas valider une modification qui aurait gagné davantage de matchs par hasard (en l'occurence la plupart des outils comme cutechess-cli utilisent SPRT).

  • [^] # Re: 1 worker process pour nginx ?

    Posté par  . En réponse au journal Le TapTempo du web, mais plus rapide. Évalué à 1.

    Et sur ta machine, quel est le temps CPU en mono-thread des processus Java, wrk avec Java, puis Rust, et enfin wrk avec Rust ?

    Selon vmstat, avec varnish je suis à 100%, en rust à 90%, java à 50% (avec 6 cœurs).

    wrk utilise entre 0.7 et 1.5 cœurs selon les benchs, et j'ai des trucs divers qui utilise 0.7 cœurs.

    Le CPU n'est occupé qu'a 12 %, et wrk prend autant de temps CPU que le processus Java…

    Tu as 16 cœurs ?

  • [^] # Re: Version Java multi-thread

    Posté par  . En réponse au journal Le TapTempo du web, mais plus rapide. Évalué à 1.

    Tel que je comprends la doc, il n'y a que les handlers de requête qui sont parallélisés. Du coup à partir du moment où tout ce qui n'est pas handler utilise 100% de CPU, ça ne sert à rien d'ajouter davantage de parallélisme.

  • [^] # Re: Varnish vs nginx et biais de configuration

    Posté par  . En réponse au journal Le TapTempo du web, mais plus rapide. Évalué à 2.

    nginx aussi compile, il utilise LuaJIT :)

    Concernant Varnish, ton lien indique :

    Note

    If you run across tuning advice that suggests running one thread pool for each CPU core, rest assured that this is old advice. Experiments and data from production environments have revealed that as long as you have two thread pools (which is the default), there is nothing to gain by increasing the number of thread pools.

    Cela dit c'est complètement possible que j'aie raté des choses.

  • [^] # Re: 1 worker process pour nginx ?

    Posté par  . En réponse au journal Le TapTempo du web, mais plus rapide. Évalué à 3.

    Vu que dans les programmes déjà existants Java était single-threadé et Rust multi-threadé la question se posait, et j'ai préféré prendre ce qui était le plus performant dans une configuration relativement standard.

    Avec node.js en mode cluster on arrive à :

    Requests/sec: 140514.83
    Transfer/sec: 26.00MB
    

    soit 4.5x la perf. monothreadée, donc un scaling quasi-linéaire (sur les 6 CPUs, 1 CPU était pris par wrk, et 0.7 par d'autres process).

    const http = require("node:http");
    const { cpus } = require("node:os");
    const cluster = require("node:cluster");
    
    const numCPUs = cpus().length;
    
    if (cluster.isPrimary)
      for (let i = 0; i < numCPUs; i++) {
        cluster.fork();
      }
    else {
      const server = http.createServer((req, res) => {
        if (req.path !== "/") res.writeHead(404);
    
        res.writeHead(302, {
          location: `https://avatar.spacefox.fr/Renard-${Math.round(
            Math.random() * 10
          )}.png`,
        });
    
        res.end();
      });
    
      server.listen(8000);
    }
  • # Conteneurs

    Posté par  . En réponse au journal Golang, oops you did it again. Évalué à 5.

    Donc pour l'instant, AMHA, les generics ne servent pas à grand chose si ce n'est composer des interfaces.

    Je dirais qu'ils servent surtout à gérer les conteneurs et les fonctions qui opèrent dessus en ignorant le contenu de façon simple, type-safe et sans codegen.

    Par exemple, le package sort permet de trier un slice en utilisant la fonction https://pkg.go.dev/sort#Slice qui n'est pas vraiment ergonomique (je dirais même pas sûre).

    Avec les génériques on pourrait avoir func Slice[T any](x []T, less func(xi, xj *T) bool) à la place.

    Pour prendre un exemple plus compliqué, l'outil dataloaden permet de générer du code pour un pattern "dataloader", ie. permettre d'avoir une fonction fn(T): U dans l'interface publique, et d'avoir le traitement implémenté dans une fonction fn2(T[]): U[], qui est appelée beaucoup moins de fois que fn (et donc optimiser plus facilement le traitement). Aujourd'hui c'est fait avec de la codegen, et ce serait beaucoup plus ergonomique avec des génériques (compilation plus rapide que la codegen, pas besoin de déclarer la liste des variantes à générer, facile d'adapter le code, etc.)

  • [^] # Re: Et la version courte ?

    Posté par  . En réponse au journal Exercices de programmation et benchmarks. Évalué à 3.

    La même chose en Haskell :

    import Data.List
    
    msum =
      sum . map sum . map (takeWhile $ (<) 0) . transpose
    
    main = do
      print $ msum [[0, 2, 3],[1, 0, 4],[5, 6, 7]]
  • [^] # Re: Tu tiens pas tes promesses

    Posté par  . En réponse au journal recherche-totoz en JavaScript. Évalué à 3.

    De plus, ça force à écrire les fameuses callback dont parle l'auteur, mais avec une variante en utilisant la "arrow syntax" (qui ne propage pas le this dans les callback), qui est courte et élégante.

    En quoi utiliser des fonctions avec l'arrow syntax est plus court et élégant que ne pas en utiliser du tout ?

    Avec cette syntaxe, une autre chose que j'aime bien: on a pas besoin de déclarer ses variables (const toto) vu qu'on les récupère directement en paramètre des closures et on peut arriver à un stade où on peut considérer que déclarer des variables est une erreur de programmation

    Absolument pas. Non seulement c'est possible de ne pas déclarer de variables temporaires avec async/await, mais surtout en déclarer n'est pas une erreur de programmation et rend le code plus clair.

    Quand on écrit const xml = await res.text() ou const totozList = obj.totozes.totoz.length ? obj.totozes.totoz : [obj.totozes.totoz], il suffit de lire le nom de la variable pour savoir ce qui est retourné.

    on rajoute des embranchements et la complexité cyclomatique et donc on augmente la probabilité d'avoir des bugs (certains analyseurs statiques d'ailleurs mettent ça en valeur).

    Je ne vois absolument pas en quoi une structure de type

    r1 = f1()
    r2 = f2(r1)
    r3 = f3(r2)
    

    ajoute quoi que ce soit en complexité par rapport à f3(f2(f1())).

    Par ailleurs, avec les promesses, on ne mélange pas les scopes, et donc on ne partage pas les variables: on réduit par la même occasion les chances d'écrasement ou d'utilisation de variable accidentels de par cette isolation

    Dans l'exemple, tout est déclaré avec le mot-clé const, rien ne peut être écrasé. Par ailleurs rien n'empêche d'appliquer les bonnes pratiques comme donner des noms clairs aux variables et écrire des fonctions courtes en utilisant async/await.

  • # Chipotage

    Posté par  . En réponse au journal Le microprocesseur, ce monstre de puissance qui passe son temps à attendre. Évalué à 10.

    Si vos données sont sur un SSD au format M.2, cas le plus favorable, vous en avez pour une petite journée (au moins 5h30) de recherche à la bibliothèque (plus de 0.02 ms, soit plus de 20 000 ns… et donc 80 000 instructions2).

    Le cas le plus favorable, c'est un SSD NVMe, qui communique directement sur le bus PCI Express. Le format M.2 permet d'utiliser des SSD NVMe mais aussi SATA.

    C'est aussi possible d'utiliser des SSD NVMe sans port M.2, qui se branchent sur un connecteur PCI Express classique.

  • [^] # Re: Définition implicites ?

    Posté par  . En réponse au journal Non, l'inférence de types n'est pas du typage faible. Oui, elle rend les programmes plus lisibles. Évalué à 3.

    le message d'erreur se trouvera a l'appel de la fonction et non a la définition/implémentation de celle-ci

    Effectivement, comme tu ne tapes pas le type de retour, tu n'auras pas de message d'erreur si le type de retour n'est pas celui que tu t'imaginais dans ta tête (tant que tu n'auras pas écrit une autre fonction qui appelle la 1ère).

    Cependant ce n'est pas un problème :

    • Ce que je fais (et je ne dois pas être le seul), c'est de regarder le type que retourne la fonction dans l'éditeur, et modifier la fonction jusqu'à ce qu'elle retourne le type voulu. Ou alors ne pas la modifier et garder le type retourné (ça arrive très souvent que le type "naturel" soit mieux que ce que je pensais vouloir à l'origine)
    • Quand tu écris une autre fonction qui appelle la première, peu importe que le message d'erreur apparaisse au niveau de la fonction appelée ou appelante : tu dois de toute façon décider si le mieux est de modifier la fonction appelée ou appelante (par exemple dans l'exemple du journal, si tu préfères que la fonction getTemp retourne un nombre ou si tu vas te débrouiller avec la chaine retournée).