[C#] pooling et non monobehaviour classes

Pour les scripts écrits en C#
Règles du forum
Merci de respecter la NOMENCLATURE suivante pour vos TITRES de messages :

Commencez par le niveau de vos scripts
DB = Débutant
MY = Moyen
CF = Confirmé

Puis le domaine d'application
-RS = Réseau
-AL = Algorithmie

Exemple :

[DB-RS] Mouvement perso multijoueur
Avatar de l’utilisateur
yoyoyaya
Messages : 1656
Inscription : 30 Mai 2011 13:14
Localisation : PAAAAARTOUUUU
Contact :

[C#] pooling et non monobehaviour classes

Message par yoyoyaya » 11 Août 2015 00:04

Lu les gens. Petite question.
Je fais du pooling pour mes gameobjects sur mes projets. Quand j'ai un go qui ne me sert plus, au lieu de le détruire, je le recycle au cas où j'aurais besoin d'en recréer un nouveau plus tard.
la question est, est-ce utile d'en faire de même pour des classes non monobehaviour ?
Je stock plein de données dans des classes écrites pour. Je créé un tas de ces classes (que je stock par exemple dans des lists et arrays) et dans chacune, j'y stock ce que j'ai à y stocker.
Maintenant, il se peut que à un moment donné, je n'en ai plus besoin. Est-ce utile de les recycler (pour une possible futur utilisation) comme je le fais pour mes go ?

Exemple bidon:

Code : Tout sélectionner

using UnityEngine;
using System.Collections;

public class A{
    public string a;
    public string b;
    public string c;
}

Code : Tout sélectionner

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class Main : MonoBehaviour{
    public List<A> a = new List<A>();
    
    void Start(){
        for(int i = 0; i < 100; i++){
            A aa = new A();
            aa.a = "bla " + i;
            aa.b = "blabla " + i;
            aa.c = "blablabla " + i;
            a.Add(aa);
        }
    }
}
Disons que je n'ai plus besoin des données stockées à la troisième position de la List. Mais que je risque dans le futur de créer de nouvelles instance de ma classe A.
Devrais-je tout simplement faire

Code : Tout sélectionner

a.RemoveAt(2);
A aa = new A();
ou alors faire quelque chose comme

Code : Tout sélectionner

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public static class Recyclage{
    private static List<A> aStock = new List<A>();
    
    public static void Recycle(A a){
        a.a = null;
        a.b = null;
        a.c = null;
        aStock.Add(a);
    }
    
    public static A New(){
        if(aStock.Count > 0){
            A a = aStock[0];
            aStock.Remove(Stock[0]);
            return a;
        }
        else{
            return new A();
        }
    }
}

Code : Tout sélectionner

Recyclage.Recycle(a[2]);
a.RemoveAt(2);
A newA = Recyclage.New();
Si quelqu'un voit où je veux en venir. Est-il utile de recycler (pooling) les scripts non monobehaviour comme on le fait pour les GameObjects et leurs composants ?

J'ai beau utiliser unity depuis un bout maintenant, ces spécificités techniques, ce n'est pas trop mon fort.
Merci
yoyo
ImageImage

Avatar de l’utilisateur
Titan
Messages : 582
Inscription : 12 Sep 2011 13:54
Contact :

Re: [C#] pooling et non monobehaviour classes

Message par Titan » 11 Août 2015 12:11

Si tu identifie un point vraiment critique il est peut être intéréssant de faire une pool (par exemple une liste de ~3000 objets que tu devrait impérativement recréer à chaque frame), pour le reste ne le fait pas, la différence, si elle existe ne sera pas perceptible (ça pourrait même nuire à tes perfs, en fait, vu que le runtime peu éventuellement effectuer lui même du pooling).

La règle général c'est de n'optimiser qu’après avoir vu un problème en testant, et identifié l'origine avec le profiler... et dans la mesure du possible faire un benchmark rapide avant et après ton optimisation pour quantifier le gain et t'assurer que tu n'a pas fait pire que mieux (c'est très fréquent, surtout dans un environnement managé).

edit pour un débutant qui lis les topic en diagonal:
je parle bien des objets non managé par unity, les GameObject de "bullet" et d' "explosion" doivent bien sûr être dans une pool car Unity fait beaucoup de travail supplémentaire à l'instanciation (https://unity3d.com/learn/tutorials/mod ... ct-pooling)
____________________________________________
Hop Boy

Avatar de l’utilisateur
yoyoyaya
Messages : 1656
Inscription : 30 Mai 2011 13:14
Localisation : PAAAAARTOUUUU
Contact :

Re: [C#] pooling et non monobehaviour classes

Message par yoyoyaya » 11 Août 2015 21:05

C'est bien ce que je pensais. Merci à toi titan :cote:
ImageImage

Avatar de l’utilisateur
minirop
Messages : 184
Inscription : 25 Juin 2014 12:58

Re: [C#] pooling et non monobehaviour classes

Message par minirop » 11 Août 2015 22:10

pour faire simple, le pooling n'est intéressant que si tu instancies ET détruis beaucoup d'objets régulièrement (une balle de pistolet est un bon exemple). Alors que pour les NPC d'un (petit) jeu, ça n'a pas grand intérêt.
Développeur Nintendo & PS Vita RIP PSM. Vive moi. Vive Unity. Flappikachu Vita

Avatar de l’utilisateur
david.dnastudios
Messages : 38
Inscription : 11 Mars 2015 10:17

Re: [C#] pooling et non monobehaviour classes

Message par david.dnastudios » 14 Août 2015 08:24

Lorsque tu fais du pooling avec Unity, c'est surtout pour éviter de lancer des Instantiate() à tout va qui sont très coûteux en perf.

De la même manière, il est intéressant de faire du pooling en programmation lorsque la création et destruction d'objets devient coûteuse. Est-ce que c'est le cas pour toi ? Si tu as une classe A avec 3 champs, je ne suis pas sûr. Selon le MSDN, tu devrais utiliser un ConcurrentBag. Par contre, tu peux considérer l'usage de struct si cela rentre dans ton cas ?

A+

David

Répondre

Revenir vers « (C#) CSharp »