Pregunta

Tengo una función que consiste principalmente en una gran cantidad de llamadas (50+) a otra función que inserta datos en una matriz, con lógica aquí y allá que dicta varias condiciones para insertar varios elementos en la matriz (más un poco en el extremo que escribe el contenido de la matriz en un archivo). Me pregunto si no hay una mejor manera de hacer esta función; Supongo que podría comenzar con la división lógica de los conjuntos de comandos de inserción de matrices en sus propias funciones, pero me pregunto si hay algo más que pueda hacer. Hay?

Ejemplo:

function buildTable(fileName, data)
    local dataToWrite = {}
    table.insert(datTWrite, {
        Type = "type1",
        Key = "someKey",
        Value = data.SomethingInteresting
    })
    --and so on ad nauseum with an occasional but of actual logic to spice things up
    dataWriter:open(fileName .. ".bla")
    dataWriter:batchWrite(dataToWrite)
    dataWriter:close()
end

En este caso, dataWriter es una instancia de una clase predefinida que maneja el proceso de escritura en un archivo.

¿Fue útil?

Solución

La buena noticia es que no has entrado directamente en la pesimización común de Lua de concatenar cadenas en un búfer en un bucle para construir tu salida.

Escribiría su muestra de esta manera:

function buildTable(fileName, data)
    local t = {}
    t[#t+1] = {
        Type = "type1",
        Key = "someKey",
        Value = data.SomethingInteresting
    }
    --and so on ad nauseum with an occasional but of actual logic to spice things up
    dataWriter:open(fileName .. ".bla")
    dataWriter:batchWrite(t)
    dataWriter:close()
end

que tiene la pequeña ventaja de no usar un nombre largo y propenso a la tipografía para la tabla temporal, y usa el lenguaje t [# t + 1] para extender la parte de la matriz, que debería ser más rápida que llamando a table.insert () .

De lo contrario, la fuente de cualquier mejora estructural estará en " y así sucesivamente ad nauseum " parte del código.

  • Busque los cálculos y fragmentos comunes que se pueden recopilar en las funciones locales.
  • Recuerde que puede anidar definiciones de funciones, por lo que las funciones de ayuda se pueden restringir en el alcance al lugar en el que se usan.
  • Busque una lógica demasiado inteligente y reescribalas para que sean sensibles a quien tenga que mantenerla el año que viene.
  • wiki: Lua Design Patterns
  • wiki: Zen Of Lua
  • wiki: Sugerencias de optimización
  • wiki: Perfilando el código Lua

Por encima de todo, cuidado con la optimización prematura. Evalúe lo que tiene ahora como un punto de comparación y úselo como una guía para encontrar cuellos de botella en el rendimiento.

Otros consejos

Por " y así sucesivamente ad nauseum con una lógica ocasional pero de lógica real para condimentar las cosas " Supongo que quiere decir que tiene muchos bloques como:

table.insert(datTWrite, {
    Type = "type1",
    Key = "someKey",
    Value = data.SomethingInteresting
})

El único aspecto de este que es exclusivo de la función es la tabla que se está rellenando y el objeto data . Mi personal "mejores prácticas" sería sacar todo esto en una tabla separada como:

local entries = {
    {
        Type = "type1",
        Key = "someKey",
        ValueField = "SomethingInteresting",
    },
    {
        Type = "type2",
        Key = "someOtherKey",
        ValueField = "SomethingElse",
    },
    -- etc.
}

Esta tabla debe ser global o en un ámbito fuera de donde se define la función. Ahora puede reconfigurar las entradas más fácilmente sin realizar ningún cambio en la función que realiza el trabajo real. La función en sí misma se simplifica enormemente al iterar a través de las entradas, por lo que:

for i, entry in ipairs(entries) do
    table.insert(datTWrite, {
        Type = entry.Type,
        Key = entry.Key,
        Value = data[entry.ValueField]
    })
end

Para el " ocasional " En la lógica, cada entrada podría tener una función opcional para proporcionarle información interesante en el bucle. Por ejemplo:

for i, entry in ipairs(entries) do
    if not entry.CheckSomething or entry.CheckSomething() then
        table.insert(datTWrite, {
            Type = entry.Type,
            Key = entry.Key,
            Value = data[entry.ValueField]
        })
    end
end

Alternativamente, incluso podría permitir que las entradas individuales en la tabla sean funciones de BE si necesita más personalización. Cada función de entrada devolvería una tabla (o no).

for i, entry in ipairs(entries) do
    if type(entry) == "function" then
        local newEntry = entry()
        if newEntry then
            table.insert(datTWrite, newEntry)
        end
    else
        table.insert(datTWrite, {
            Type = entry.Type,
            Key = entry.Key,
            Value = data[entry.ValueField]
        })
    end
end

Sin nada específico para continuar, intentaría investigar olores de código y ver cómo se compara su función. Por los sonidos de las cosas, es probable que haya mucho que hacer. ¿Hay bloques de código similar / copiado aislados por lógica condicional diferente? ¿Bucles anidados o condicionales? Estos son algunos puntos de partida simples cuando se trata de dividir una función grande en partes.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top