L'aumento del numero di classi ha un impatto sulle prestazioni

1

Sono nel mezzo del refactoring di un progetto (in C ++ 11) e sto lottando con una decisione è bello cambiare enum enorme con circa 100 record per classi separate. Questo enum è utilizzato in circa 4 posizioni nel codice in 4 diverse funzioni con enormi istruzioni switch. Per ogni enum, il record è un codice in ogni funzione.

Sto pensando di creare un'interfaccia e li implementano in classi, ma il numero di classi nel progetto aumenterà di 100. Ecco perché sono preoccupato se questo mi costerà un calo delle prestazioni o avrà un impatto enorme su utilizzo della memoria o avrà altre conseguenze. So che il codice sarà in condizioni migliori ma è anche molto importante che funzioni velocemente (non estremamente veloce) ma è un'applicazione server, quindi è un fattore importante.

Alcuni esempi di codice:

enum MyEnum {
  RECORD_1,
  RECORD_2,
  ...
  RECORD_100
}

void doSomething(MyEnum en) {
  switch (en) {
  case RECORD_1: {

  } break;
  case RECORD_2: {

  } break;
  //...
  case RECORD_100: {

  } break;
  };
}

void doSomethingElse(MyEnum en) {
  switch (en) {
  case RECORD_1: {

  } break;
  case RECORD_2: {

  } break;
  //...
  case RECORD_100: {

  } break;
  };
}

Quindi sto pensando a creare un'interfaccia:

class AbstractInterface {
public:
  virtual void doSomething() = 0;
  virtual void doSomethingElse() = 0;
};

E quindi implementa questa interfaccia nelle classi:

class Record1 : public AbstractInterface {
public:
  void doSomething() override;
  void doSomethingElse() override;
};

//...

class Record2 : public AbstractInterface {
public:
  void doSomething() override;
  void doSomethingElse() override;
};

È un buon modo per refactoring questo tipo di codice in questo modo? e non diminuendo le prestazioni dell'applicazione?

    
posta Piter _OS 18.04.2018 - 10:13
fonte

2 risposte

7

Non ci sarà un enorme cambiamento nelle prestazioni. La tua soluzione attuale utilizza un grande switch / caso per la spedizione, la tua soluzione proposta utilizza la spedizione dinamica. Entrambi implicano un po 'di indirezione e / o ramificazione. Entrambi sono essenzialmente lo stesso codice.

Ci sono un paio di minuscole differenze che potrebbero far sì che l'interruttore sia leggermente più veloce:

  • Gli enum sono tipicamente supportati da ints, ma i tuoi oggetti saranno probabilmente un puntatore all'oggetto + un puntatore vtable all'interno dell'oggetto. Quindi, ad esempio, potresti avere un utilizzo di memoria superiore a 4 ×, oltre a puntatori indiretti aggiuntivi. È rilevante? Probabilmente no, a meno che non stiate memorizzando molti milioni di istanze contemporaneamente.

  • Il codice per i diversi rami nello switch sono l'uno accanto all'altro, il che potrebbe essere utile per la memorizzazione nella cache. Al contrario, gli oggetti, i vtable e i corpi dei metodi per i tuoi oggetti potrebbero essere dappertutto. Quando si chiama un metodo usato raramente, il processore dovrà attendere fino a quando i dati non verranno caricati nella cache. OTOH lo switch potrebbe essere così grande da non essere mai completamente caricato nella cache, quindi potrebbero esserci gli stessi svantaggi.

Ci sono certamente degli scenari in cui la programmazione cache-friendly fa una grande differenza. Per la maggior parte del codice, non è così. Vorrei sottolineare che molti linguaggi come Java o Python hanno inefficienze fondamentali nel loro modello a oggetti, ma offrono comunque prestazioni accettabili in molte applicazioni.

    
risposta data 18.04.2018 - 12:15
fonte
2

I'm thinking about creating an interface and them implement in classes but the number of classes in project will increase by 100.

Non ti preoccupare.

Anche un programma base, "Hello World", probabilmente usa [almeno] molte classi dal .Net Framework.

Le tue 100 classi ciascuna delle quali "fa la sua parte" saranno lontano più mantenibili a lungo termine rispetto ai tuoi attuali, quattro metodi che devono "sapere tutto su 100 diverse classi" .

    
risposta data 18.04.2018 - 12:16
fonte

Leggi altre domande sui tag