What would be a more Efficient way of Handling Data?

So, Lets say I’m trying to make my own DataStore type System, I want it to Save whatever I need it to, and to do it efficiently without suffering many Problems to it, Here I am trying to load Data by using GetAsync, using OOP (Object Oriented Programming), which wrapped in a pcall, should look like this:

local success, result = pcall(DataStore.GetAsync, DataStore, self.Key)
-- success is the variable that will tell us if the operation was successful
-- result for this usage will give us the Following Data:

--- Success Responses:
--/ 1: Data from the Specified Key
--/ 2: No data from the Specified Key (Simplified: nil )

--- Error Responses:
--/ 1: Error 

This works as Intended, There is nothing wrong with the way its formatted, and we can Handle the Errors Properly, if you were thinking normally, you would probably do the following, which is a very common way that people do it, or teach you how to do it:

if success then -- if the operation was successful
    if result then -- if there is Data
        print("Data Loaded")
        return result
    else -- if there is no Data
        warn("No Data Found")
        return StarterData
    end
else -- if the operation Failed
    warn("DataStore Failed to Load")
end

As you can see, its pretty normal, should work as intended, but it can be further simplfied with the usage of the keywords and, and or, without the If statement they work slightly differently, and can be used for many Different Purposes, they are very useful, and tend to have your code look shorter.

Another thing we can do is to use a Boolean, the if statements will check if something is true, so with the usage of and, and or, we can check.

But then we are able to format our code like this because of how Lua’s Syntax works:

--- Method 1:
local Data = success and result and result or StarterData
-- if success is true and result is true then result
-- otherwise you will get Starter Data

--- Method 2:
local Boolean (result ~= nil)
-- Boolean will return a Boolean depeding if the current statement is true or not
-- if its nil or false, its false, otherwise its true

local Data = Boolean and result or StarterData
-- if the Boolean is true then it would be our Data
-- otherwise its replaced by StarterData

--- Method 3:
result = result or StarterData
-- if result is true then it will be itself
-- otherwise it will be replaced with StarterData

Which shortens the code by a little bit.

But this isnt some Tutorial, and Sorry if I make it look like one, I’m just here to ask about the Efficiency of the Following codes, and whether they are better to use or not.
While these may be shorter than the other, it may not make them faster, so what would be better to use?

You should have posted it in #help-and-feedback:code-review.
Asides from that, code is pretty optimal, I don’t see any issue here.

This isnt reviewing code though.
Its asking a Question about if something is more efficient than the other.

Also, Code Review is kind of dead.

This… is exactly code review. You are asking people to review if your code is efficent.

Well I do agree on that.

2 Likes

I suggest to write this as

local Data = (success and result) or StarterData

This basically means:

if success and result then 
   return result
else -- elseif StarterData then would give the same result when nil
   return StarterData
end

Also the brackets do help making sure everything works as expected, there would be no chance it wouldn’t work then.

Honestly I do think it’d be more efficient to do something like that, but at the same time there might already be saved data, but it does not include a certain value (because you’ve added that later) then you have to look out for that as well.

1 Like

Whoops.

I already know that

Edit: (there is a minor mistake in that, it would just be if success then result, not if success, and result then result, which is what success and result and result did)

They are parenthesis, not brackets, but no that doesnt really happen, Its not like math where it solves it by using PEMDAS or BEDMAS.
There might be a case where its used, but this isnt one of them, I just do it for readability reasons.

some observations

This code works well but is not efficient in the long run. What if you are loading several data at the same time, like when the user joins the game? In that case you would be calling as many pcalls as data. It would be more efficient to call only one pcall for all of them.

As for using logical operators to make decisions, it was a way to hack the language to get a decision expression, like the ?: ternary operator of c. However luau already has an if expression so there is no need to use the logical operators. As far as efficiency is concerned, I doubt there is any significant difference.

by the way your methods 1, 2 and 3 are not entirely safe. what if a data is a boolean? in that case result will sometimes be false and the result of the expression will be StarterData even if it succeeded.

1 Like

Thats why you use tables, store all the Data under one key instead of multiple.
I’m not sure where you are going with this because nobody said anything about that.

Its a table, Pretty sure it wont be boolean, Even if it was, its as simple as == false, ~= false, == nil and ~= nil.

So during the game, when you want to update a single piece of data you would have to update the whole table. It is better to have separate data.

You didn’t say that in the beginning. So this post is not about data in general but about a particular case.

1 Like

But you can do this:

ValueBase.Changed:Connect(function(newValue)
    Session[player.UserId][item] = newValue
end)

Have a Session table hold the Players Data, and use either an Attribute, or ValueBase, when it changes on the Server Side, you can update the Index with that value, that is at least how I usually handle it.

When the Player leaves, you can then Save that Data, Updating the Entire table seems a bit overboard, and Having Multiple Keys for Separate Pieces of Data that can be put together would be inefficient.

But this isnt really related to the Topic, and I dont really want to go off topic so yeah, thats about it

I didnt really need to, its just a question whether to use an if statement, or the keywords, and, and or, thats really all I’m wondering about, not about what if this is this, I appreciate it, but its not really what I’m asking about.

It seems that using an if-then-else expression is shorter than using an if statement, and it should be preferred over the x and y or z expressions.

Checking if result isn’t nil:

local data = if success and result then result else starterData

Checking if success is true or false, too:

local data = if not success
  then nil -- You could replace this with `result`.
  elseif success and result then result
  else starterData

Or you can do this, relating to the comment inside the last snippet:

local data = if not success or success and result
  then result
  else starterData

The Luau-lang and Roblox Lua Style Guide websites go a little deeper into if-then-else expressions and why they should be used to replace a and b or c-type expressions. I am on my phone, so it requires more from me to provide the links.

1 Like

Efficiency is irrelevant in this situation; you’ll see no meaningful performance differences in practice from any of the described methods. Robustness should be the focus of data management.

The forked method is preferable to any of the ternary-style implementations because it explicitly handles all cases. The case where the DataStore call fails is an important case to handle, and returning a default table is generally too narrow of an approach to handle that issue without introducing data loss concerns.