-
-
Notifications
You must be signed in to change notification settings - Fork 37
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Global vs Local Variables #39
Comments
Hmm, interesting. I think a better way to manage it would be to have our 'private' variables being assigned as fields of the module it is relevant to. For example, with the 'clipboard.lua' file now, instead of this: local log = hs.logger.new("clipboard") I would try something like this: local mod = {}
mod.log = hs.logger.new("clipboard")
-- other code goes here
return mod The main downside is that you then have to add log.d("A debug message!") to this: mod.log.d("A debug message!") Not the end of the world, and I believe it would resolve the GC issue without making everything a global, which potentially would introduce clashes between different files. |
I'm not sure that solves the issue though...
Please correct me if I'm wrong, but as Does that make sense? |
We may have to make the 'fcpxHacks' module global. But if all the other variables are on that module, they shouldn't get GC'd because they are still linked to the fcpxHacks module. It will require some testing to see if it actually works. I'll have a look into it. |
…l/local garbage collection issues.
Really awesome work @randomeizer ! Not sure if you've seen my fumbling around yet, but eventually I'd like to move all the "Final Cut Pro" commands into the one module - so that if anyone else wants to build something similar to FCPX Hacks, they've got an easy starting point. I've started doing this really roughly for #45. |
Yeah, I'd like to split up the different functional parts into separate files, similar to 'clipboard.lua', for example. It will help with keeping the code readable and manageable. |
I'm thinking that we should maybe do the modularisation through individual issue tags though, and maybe wait until I've done the initial work here in #39, or we may end up stepping on each other's toes. My goal in this one is to make sure everything is safely in a global, or linked as a sub-property in |
…d as globals, or as fields of fcpxHacks.
FYI, I decided to switch to using 'hs.xxx' to reference built-in Hammerspoon libraries. It's kind of redundant creating a tonne of globals for those and/or assigning them as 'mod.xxx', when it's just three extra characters to reference the built-in globals directly. This won't work with the non-standard extensions (touchbar, etc), but will be fine for most things we use. |
Agreed! I was originally against it, as I thought it would slow me down, or slow the code down, but in retrospect, I think it's a really great idea. Thank you!
Yep - agreed. The only stuff I've added in #45 thus far is now plist functions, so it shouldn't affect anything.
Ummm... I'm not sure about that one. I believe there's a very slight speed increase by calling it locally. This speed increase was actually noticeable, when I was originally trying to get the GUI Scripting stuff to work. In regards to Global vs Local, have a read of this and let me know what you think! |
…he global function defined in the fcpxhacks/init.lua
We would be making the globals either way. The only difference is whether you make an additional table property lookup by adding the If there are specific tasks that are measurably slower, we can optimise those. But in general, I think this is a better way. Can you recall the specific activities that were slower? |
Sorry to be a pain, but I'd much prefer it if the code didn't have "hs." everywhere. I feel like it just makes things messy for no real benefit. I liked it the way it was, because it allowed to code things really quickly as easily. Sorry - I know it's only three characters of extra typing, but I'm lazy, and I like things to look as simple as possible. In terms of speed, to dig up an older conversation...
So in terms of speed, it probably doesn't make any substantial difference, but I guess technically it's faster (in micro/nano seconds!) - so I reckon we just do it. Sorry! |
The thing is, when you do this: alert = require("hs.alert") you are making them globals, not locals. There are two issues with this:
For example, in our project, we do the above in This is typically not such a big issue for our 'requires', because they would have a fairly standard name, and it's loading the same library. But it is potentially a much bigger one for variables being used inside a module, since it's not completely obvious what globals a given module is defining. To me, having 'hs.' in front of standard Hammerspoon class calls is actually making the code clearer. It clearly says, this is a standard library, and doesn't have any dependency on global variables which may be defined in other modules. |
No worries! Well, rather than making them global, would you have any objections if we made them local to each LUA script? For example:
In retrospect, I'm not even sure why I made all these "extensions" global in the first place! I think it was because I couldn't get this to work:
...so I just said, "screw it", and made them all global. |
Making them local would help. The fix for the problem you mentioned, assuming you are also requiring 'hs.window', would be this: local window = require("hs.window")
window.filter = require("hs.window.filter") However, you may find that window.filter will just work anyway - not sure though. Haven't tested that. |
Let's do that then... let's just make them local, so I can be happy not typing "hs." all the time. Thanks for all your help @randomeizer ! Once you're done with issue #39, I'll update Hopefully once all this "plumbing" stuff is done, I can get back to adding new features again! |
So, I did some benchmarking. Ran a simple operation (
So, running each operation 1 million times took about 7.8 to 8.1 seconds, depending. Each operation was taking around of 0.008 milliseconds (aka 8 nanoseconds) to run. Which method was fastest varied on each run, although the The upshot is, performance-wise, it doesn't matter whether we use Here's the benchmark code, for your reference: -- local/global/hs speed tests
function benchmarkAccess(count)
print("Round "..count..":")
local clock = os.clock
local max = 1000000
local start, result
-- Use global hs. namespace
start = clock()
for i=1,max do
hs.hash.MD5("Foobar")
end
result = clock()-start
print("hs.hash.MD5('Foobar') x "..max..": "..(result*1000).."ms total/"..(result/max*1000).."ms avg")
-- Use a global from require
globalHash = require("hs.hash")
start = clock()
for i=1,max do
globalHash.MD5("Foobar")
end
result = clock()-start
print("globalHash.MD5('Foobar') x "..max..": "..(result*1000).."ms total/"..(result/max*1000).."ms avg")
-- Use a global from require
local localHash = require("hs.hash")
start = clock()
for i=1,max do
localHash.MD5("Foobar")
end
result = clock()-start
print("localHash.MD5('Foobar') x "..max..": "..(result*1000).."ms total/"..(result/max*1000).."ms avg")
end
print("Benchmarking hs/global/local access speeds\n")
for j=1,5 do
benchmarkAccess(j)
end I just pasted it into the end of the |
Ok, locals they are then. |
Legend, thanks mate! |
…d to a module, as appropriate. * Made ‘require’ imports locals. * Renamed the clipboard local values to ‘clipboard.xxx’
…priate function if the did not to be module-wide variables.
@randomeizer - As discussed on Skype, here's that discussion I was talking about in regards to global vs local variables.
The text was updated successfully, but these errors were encountered: