Qualche punto nell'utilizzare ES6 Map quando le chiavi sono tutte stringhe?


36

Le chiavi oggetto semplici devono essere stringhe, mentre a Mappuò avere chiavi di qualsiasi tipo.

Ma in pratica mi serve poco. In quasi tutti i casi, mi ritrovo ad usare le stringhe come chiavi comunque. E presumibilmente new Map()è più lento di {}. Quindi c'è qualche altro motivo per cui potrebbe essere meglio usare un oggetto Mapanziché un oggetto semplice?


3
MDN , come al solito, ha un buon confronto.
Chris Hayes,

1
Cordiali saluti, Mappa sembra essere più veloce sia per l'impostazione che per ottenere.
Aprire il

@mpen - jsperf non funziona più. Sei sicuramente map.set('foo', 123)eseguito più velocemente di obj.foo = 123? Se è così è molto sorprendente
callum,

@callum Uhh..no, non positivo. Potresti voler scrivere alcuni nuovi test delle prestazioni.
aprono il

Risposte:


42

Ci sono alcuni motivi per cui preferisco usare Maps su oggetti semplici ( {}) per archiviare i dati di runtime (cache, ecc.):

  1. La .sizeproprietà mi fa sapere quante voci esistono in questa mappa;
  2. I vari metodi di utilità - .clear(), .forEach(), ecc;
  3. Mi forniscono iteratori di default!

Ogni altro caso, come il passaggio di argomenti di funzioni, la memorizzazione di configurazioni e così via, sono tutti scritti usando oggetti semplici.

Inoltre, ricorda: non tentare di ottimizzare il codice troppo presto. Non perdere tempo a fare benchmark di oggetti semplici e mappe a meno che il tuo progetto non abbia problemi di prestazioni.


1
Qual è la funzione hashcode di identità utilizzata da Javascript?
Pacerier,

1
@Pacerier ===:)
gustavohenke,

Le mappe sono molto più veloci degli oggetti semplici in questi giorni.
jayarjo,

@gustavohenke Non è vero. Maputilizza l'algoritmo SameValueZero. developer.mozilla.org/en-US/docs/Web/JavaScript/…
lolmaus - Andrey Mikhaylov

@ lolmaus-AndreyMikhaylov, okay, ma ho detto qualcosa Mapsull'uso di questo o quello?
gustavohenke,

4

Non ne sono sicuro, ma penso che le prestazioni NON siano un motivo per utilizzare Maps. Dai un'occhiata a questa pagina jsperf aggiornata:

http://jsperf.com/es6-map-vs-object-properties/73

Sembra che (quando si ha a che fare con le stringhe almeno) gli oggetti sono molto più veloci delle mappe per l'impostazione di base e per ottenere.


2
Non è così che scrivi i test delle prestazioni.
Qix,

6
Non è così che scrivi commenti utili. Sentiti libero di elaborare se hai una metodologia alternativa da suggerire. Cosa c'è di sbagliato nel modo in cui sono stati scritti quei test? Sono in qualche modo non validi o inutili?
Starlogodaniel,

9
La semantica / costrutti linguistici testati tramite microbenchmark devono differire di una sola variabile. I test variano in base al numero di iterazioni e alcuni di essi avranno il contenuto del loop interno ottimizzato poiché il risultato non viene utilizzato. Alcuni test pre-dichiarano le variabili mentre altri hanno la dichiarazione delle variabili in linea con il ciclo for, il che può comportare anomalie delle prestazioni diverse.
Qix,

1
Ahi, hai assolutamente ragione. A mia difesa, la mia versione è stata un miglioramento rispetto a quella precedente, ma ho perso sia il pre-dichiarare che il contenuto del loop interno in fase di ottimizzazione. Stavo lavorando con un collega che ha migliorato la mia bozza e penso che abbia risolto questi problemi: jsperf.com/es6-map-vs-object-properties/88 . Tuttavia, penso che sia valido avere stili di loop diversi per le diverse strutture di dati; nell'uso reale, le persone sceglieranno la struttura del loop con le migliori prestazioni e Map e Object hanno strutture del loop "ottimali" diverse. Comunque, grazie per la cattura.
Starlogodaniel,

Ok, ora vedo: erano più lenti degli oggetti semplici, ma sono stati fortemente ottimizzati nei browser recenti.
jayarjo,

0

Le altre risposte non menzionano un'ultima differenza tra oggetti e Maps:

L' Mapoggetto contiene coppie chiave-valore e ricorda l'ordine di inserimento originale delle chiavi .

Pertanto, quando si scorre su di esso, un oggetto Mappa restituisce le chiavi in ​​ordine di inserimento.

Citazione da MDN , enfasi mia


Questo è stato il motivo principale per cui ho deciso di utilizzare Mapper la prima volta in un recente progetto. Avevo un oggetto normale che dovevo visualizzare in a <table>, con ogni proprietà che andava in una riga specifica.

let productPropertyOrder = [ "name", "weight", "price", "stocked" ];

let product =
{
    name: "Lasagne",
    weight: "1kg",
    price: 10,
    stocked: true
}

Ho scritto una funzione per trasformare un oggetto in un Mapsecondo un ordine di tasti desiderato:

function objectToMap( obj, order )
{
    let map = new Map();

    for ( const key of order )
    {
        if ( obj.hasOwnProperty( key ) )
        {
            map.set( key, obj[ key ] );
        }
    }

    return map;
}

Quindi la mappa potrebbe essere ripetuta nell'ordine desiderato:

let productMap = objectToMap( product, productPropertyOrder );

for ( const value of productMap.values() )
{
    let cell = document.createElement( "td" );
    cell.innerText = value;
    row.appendChild( cell );
}

Naturalmente questo è un po 'inventato perché si potrebbe anche visualizzare quando si itera sull'ordine delle proprietà senza creare un Mapnel processo:

for ( const key of productPropertyOrder )
{
    if ( product.hasOwnProperty( key ) )
    {
        let value = product[ key ];
        // create cell
    }
}

Ma se hai una serie di tali oggetti e li visualizzerai in molti luoghi, allora convertirli tutti in mappe ha senso.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.