Libgdx: Limitaciones de capacidad de IntMap

Creado en 20 jul. 2020  ·  3Comentarios  ·  Fuente: libgdx/libgdx

Detalles del problema

La implementación actual de IntMap parece tener una capacidad máxima de alrededor de 11425 entradas. He probado tanto en 1.9.10 como en 1.9.11-SNAPSHOT. También intenté generar un método hashcode () y equals () para TestObject.

Vea la prueba unitaria a continuación como reproducción.

Pasos de reproducción / código

import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.RandomXS128;
import com.badlogic.gdx.utils.IntMap;
import org.junit.Assert;
import org.junit.Test;

public class IntMapTest {

    <strong i="9">@Test</strong>
    public void testLargeMap() {
        final int totalEntries = 11427;

        final float minX = -64000f;
        final float minY = -38400f;
        final float maxX = Math.abs(minX);
        final float maxY = Math.abs(minY);

        MathUtils.random = new RandomXS128(1024);

        final IntMap<TestObject> intMap = new IntMap<TestObject>(totalEntries);
        for(int i = 0; i < totalEntries; i++) {
            final TestObject testObject = new TestObject();
            testObject.x = MathUtils.random(minX, maxX);
            testObject.y = MathUtils.random(minY, maxY);

            intMap.put(testObject.getIndex(), testObject);
        }
        Assert.assertEquals(totalEntries, intMap.size);
    }

    private class TestObject {
        float x, y;

        public int getIndex() {
            final int row = MathUtils.floor(y / 8f);
            final int column = MathUtils.floor(x / 8f);
            return (row * ((64000 / 8))) + column;
        }
    }
}

Comentario más útil

Mirándolo ahora.

Todos 3 comentarios

Mirándolo ahora.

No hay problema aquí; cuando inserta la misma clave en un mapa, reemplaza el valor original con el nuevo valor y devuelve el valor original (consulte: documentos de IntMap.put () o Map.put () en el JDK). Y eso es todo lo que está sucediendo; su prueba siempre inserta 3 claves (resultados de getIndex ()) cuando esa clave ya existe en el IntMap, y 11424 se insertan sin un duplicado presente. Agregué impresiones de depuración cuando se repite un índice:

21094870 was the same as 21094870
-13869065 was the same as -13869065
-17368612 was the same as -17368612

expected:<11427> but was:<11424>
Expected :11427
Actual   :11424

Eso es 3 duplicados y 3 elementos menos en el IntMap como resultado. Si 11424 fuera un máximo estricto, lo siguiente sería imposible:

21094870 was the same as 21094870
-13869065 was the same as -13869065
-17368612 was the same as -17368612

expected:<12427> but was:<12424>
Expected :12427
Actual   :12424

Pero en realidad podemos obtener más de 11424 elementos en una implementación de Map completamente probada ... Una de las muchas pruebas que se realizaron en enero para un PR que hice involucró la evaluación comparativa de las colecciones de libGDX con 100,000 o 1,000,000 de entradas, así que estaba bastante seguro de que podría manejar 11.427.

Esta prueba expone una peculiaridad de las colecciones basadas en hash de 1.9.10, y es otra razón por la que las relaciones públicas para 1.9.11 son importantes: ObjectMap, ObjectSet, IntMap, IntIntMap, IntFloatMap, LongMap, IdentityMap, OrderedMap y OrderedSet (me perdí any?) rara vez llamará a MathUtils.random(2) internamente, lo que estropea un conjunto de llamadas deterministas a los métodos de generación de números aleatorios de MathUtils con un objeto RandomXS128 o Random inicializado. Eso significa que los flotantes entregados a TestObject son diferentes en 1.9.10, en 1.9.11 y en 1.9.10 con todas las llamadas de IntMap eliminadas (solo registrando los flotantes generados por MathUtils). Todavía no hay un límite de capacidad, y el comportamiento observado sigue siendo el comportamiento documentado esperado para un mapa, pero el tamaño real del IntMap será diferente porque el flujo de números aleatorios que se le da es diferente en libGDX 1.9.10 (1.9.11 es solo ligeramente diferente, con dos valores de repetición en lugar de 3, pero todos los números después de cierto punto son diferentes porque no compite con las llamadas de IntMap a MathUtil estático Random variable).

¡Gracias por investigar! Volveré a revisar cómo estoy calculando mis índices en el juego, pero no debería haber duplicados. Debe haber sido solo una coincidencia que siempre haya 11425 entradas tanto en el juego como en la prueba unitaria. Volveré a abrir el problema si identifico algo en el IntMap.

¿Fue útil esta página
0 / 5 - 0 calificaciones