2009-09-10 3 views
0

У меня есть функция, которая состоит в основном из большого количества вызовов (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 является экземпляром предопределенного класса, который обрабатывает процесс записи в файл.

+0

Этот вопрос недостаточно ясен. Добавить код для просвещения – Sergio

+0

Являются ли операции с данными конкретными для разных объектов? Если это так, вы можете создать дизайн класса, основанный на ваших таблицах базы данных. –

+0

Лучше подстройте мой ответ, по «таблице», я имею в виду массив, я думаю. Это проблема lua, поэтому я обращался к таблицам, но мне хотелось обобщить вопрос, чтобы он мог помочь большему количеству людей. – RCIX

ответ

2

Хорошей новостью является то, что вы не перешли непосредственно в общую пессимизацию 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().

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

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

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

0

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

2

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

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 

Для «случайной» логики, каждый элемент может иметь дополнительную функцию, чтобы дать вам интересную информацию в цикле. Например .:

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 

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

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 
Смежные вопросы