Лучший способ создать эту функцию? - PullRequest
0 голосов
/ 10 сентября 2009

У меня есть функция, которая состоит в основном из огромного количества вызовов (более 50) к другой функции, которая вставляет данные в массив, с логикой тут и там диктуются различные условия для вставки различных элементов в массив (плюс немного в конце, который записывает содержимое массива в файл). Мне интересно, если нет лучшего способа сделать эту функцию; Я полагаю, что мог бы начать с логического разделения наборов команд вставки массива на их собственные функции, но мне интересно, можно ли еще что-нибудь сделать. Есть ли?

Пример:

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

В этом случае dataWriter является экземпляром предопределенного класса, который обрабатывает процесс записи в файл.

Ответы [ 3 ]

2 голосов
/ 10 сентября 2009

Хорошей новостью является то, что вы не вступили непосредственно в общую пессимизацию Lua конкатенации строк в буфер в цикле для создания выходных данных.

Я бы написал ваш пример так:

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

, который имеет небольшое преимущество - не использовать длинное склонное к опечаткам имя для временной таблицы и использует идиому t[#t+1] для расширения части массива, что должно быть быстрее, чем вызов table.insert().

В противном случае источник любых структурных улучшений будет находиться в части кода «и так далее».

  • Найдите там общие вычисления и фрагменты, которые можно собрать в локальные функции.
  • Помните, что вы можете вкладывать определения функций, так что вспомогательные функции могут быть ограничены областью их использования.
  • Ищите слишком умную логику и перепишите ее, чтобы она была разумной для тех, кому придется поддерживать ее в следующем году.
  • wiki: Шаблоны Lua Design
  • вики: Zen Of Lua
  • wiki: Советы по оптимизации
  • wiki: Профилирование кода Lua

Прежде всего, остерегайтесь преждевременной оптимизации. Оцените, что вы имеете сейчас, в качестве точки сравнения, и используйте это в качестве руководства для поиска узких мест в производительности.

2 голосов
/ 11 сентября 2009

К "и так далее до тошноты со случайной, но реальной логикой, чтобы оживить ситуацию" Я предполагаю, что вы имеете в виду, что у вас есть много блоков вроде:

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

Единственный аспект этого, который уникален для функции, - это заполняемая таблица и объект data. Моя личная "лучшая практика" - вынести все это в отдельную таблицу, например:

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

Эта таблица должна быть глобальной или выходить за пределы области, где определена функция. Теперь вы можете легче перенастроить записи, не внося никаких изменений в функцию, выполняющую реальную работу. Сама функция значительно упрощается путем итерации записей таким образом:

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

Для "случайной" логики каждая запись может иметь дополнительную функцию, чтобы дать вам интересную информацию в цикле. E.g.:

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

В качестве альтернативы, вы можете даже разрешить отдельным функциям в таблице выполнять функции BE, если вам нужна дополнительная возможность настройки. Каждая функция ввода будет возвращать таблицу (или нет).

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
0 голосов
/ 10 сентября 2009

Без каких-либо конкретных действий я попытался бы изучить запах кода и посмотреть, как ваша функция сравнивается. Судя по звукам вещей, вам, вероятно, есть чем заняться. Существуют ли блоки схожего / скопированного кода, выделенные другой условной логикой? Вложенные циклы или условные выражения? Это несколько простых отправных точек при попытке разбить большую функцию на части.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...