I have been cleaning up some of my VERY redundant code, and wound up with a situation that is confusing me. Maybe minds with more wisdom can clear this up for me.
I have a variable that I use in a number of methods in a Module:
var myDatabase as New SQLiteDatabase
Since this will NOT change during the program (once you choose your database that is what you are working on) I figured make it a shared property:
App-> Shared Properties -> myDatabase / SQLiteDatabase / Public
But if I use it in ANY of my Methods I get a NIL.
Why? Should it not be available for any code, Method or otherwise?
Faster yes, but it’s a reduction in time in a very small amount to begin with so most people won’t notice the few milliseconds savings.
Other ideas:
create a module, and have your database be a global property of the module.
If this is a document based app, think about the situation where the user has two or more windows open at once. Maybe the database should be part of the window class, not the app?
It’s very inefficient, yes, but the actual impact on your app speed overall might not matter in many cases, especially in this situation, where the person is simply grabbing a reference to a database.
There’s a 12-year-old feature request to speed this up for anyone interested: https://tracker.xojo.com/xojoinc/xojo/-/issues/16764
I’ve signed on and would encourage others to do so. It would especially benefit anyone using App properties in a large loops. The same is true of App methods, Shared methods are currently faster.
Yes, it is still different. I’ve created an app with a Property and a Shared Property. Running the following code in a button Pressed event results in the following numbers:
#Pragma DisableBackgroundTasks Off
#Pragma DisableBoundsChecking Off
Var dStart As Double = System.Microseconds
For nLoop As Integer = 0 To 100000000
App.Prop = 1
Next
Var dStop As Double = System.Microseconds
For nLoop As Integer = 0 To 100000000
App.sProp = 1
Next
Var dStop2 As Double = System.Microseconds
#Pragma DisableBackgroundTasks On
#Pragma DisableBoundsChecking On
Var diffProp As Integer = dStop - dStart
Var diffSharedProp As Integer = dStop2 - dStop
MessageBox "Property : " + Format( diffProp, "0" ) + Chr(13) + "Shared Property : " + Str( diffSharedProp, "0" )
The 20 times was not my claim, I pointed to the source. App. is not just used once it could well be a property that is involved in a loop. Just saying it’s worth considering. My loop aves 3.4 seconds, so it can be worth while.
if you use a class with Shared Properties or Methods it can be accessed without creating the object, you could just write the classname and then the property or method name. often useful.
i use a subclass version of the database class and create the db where i need it.
if i need a query i use:
Var db As New DB
Var rs As RowSet = db.SelectSQL("Select * From table Where rowid=?", id)
class DB with Super SQLiteDatabase
Public Sub Constructor()
// Calling the overridden superclass constructor.
Super.Constructor
Self.DatabaseFile = File()
Self.Connect
End Sub
Public Sub Destructor()
Self.Close
End Sub
Public Function File() As FolderItem
Var f As FolderItem = SpecialFolder.Documents.Child("Database").Child("Office.Xojo.sqlite")
System.DebugLog f.NativePath
Return f
End Function
Good to know the difference is down to expectable values, if it really had been 20 x at a time.
Speed difference is because of every normal property and method of a class will get the instance itself passed as a hidden property. If you design a shared method that will expect an instance as input, you should theoretically find the same performance as a class method without this parameter.