Auto vs. Variant, when to use Auto?

I’m having a hard time finding a good use for Auto. Auto uses less memory and is faster than a Variant if you know its type. If you do not know its type and have to determine that, Auto is much slower than Variant. You also can not use IsA on an Auto safely.

I did a simple benchmark, assigning a String, Integer, Double and Date to a Variant and Auto 10,000 times. In the respective loops, I assigned Variant.Type to an Integer (to simulate me checking what type it is) and for Auto, assigned xojo.Introspection.GetType(var).Name to a String value (to simulate me checking what type it is).

The Variant code ran in 0.0118245 seconds while the Auto code ran in 0.2940093 seconds.

BTW, IsA will work on Auto as long as you know it is an Object. However, if you are unsure, then you may cause Exceptions in your code by using IsA on an Auto. For example, the following code will cause an exception.

dim a as Auto = 10
Print Str(a isa Date)

So, when would one use an Auto? I know it uses less memory, but none of my apps are having memory issues right now. I use Variant rarely, but when I need to, the use cases for them will be much faster than an Auto.

The second part (the potential of an exception with IsA) feels like a bug. Is it?

BTW, my benchmark code is simply:

  const its = 10000
  
  dim ms as Double
  dim s as String = "Hello"
  dim i as Integer = 10
  dim d as Double = 20.5
  dim dt as new Date
  
  dim vtype as Integer
  dim stype as String
  
  ms = Microseconds
  for j as Integer = 0 to its
    dim v as Variant
    
    v = s
    vtype = v.Type
    
    v = i
    vtype = v.Type
    
    v = d
    vtype = v.Type
    
    v = dt
    vtype = v.Type
  next
  Print Str(Microseconds - ms)

  ms = Microseconds
  for j as Integer = 0 to its
    dim a as Auto
    
    a = s
    stype = xojo.Introspection.GetType(a).Name
    
    a = i
    stype = xojo.Introspection.GetType(a).Name
    
    a = d
    stype = xojo.Introspection.GetType(a).Name
    
    a = dt
    stype = xojo.Introspection.GetType(a).Name
  next
  Print Str(Microseconds - ms)

To interrogate Auto is way slower than using a Variant (currently approx. 10 times). I trust that this will be getting better when the new framework develops.

But there are also quirks, like there is no GetTypeInfo for Xojo.Introspection, so you have to create an dummy object to get its TypeInfo. Or you cannot test if an Auto variable holding a Xojo.Core.Date is a Xojo.Core.Date with IsA. And there is more… Again I trust that this will get better over the time as the new framework is still young.

Auto is a great idea, but it needs a better API which currently is no API at all. I don’t understand why there is no Type property like with Variants. The issue with Variants was not that one could test what data type it was holding, but the implicit conversions which were built-in. So IMHO they should introduce this feature to Auto:

Dim anAuto As Auto = ... Select Case anAuto.Type Case Auto.TypeInteger ... Case Auto.TypeText ... Case Auto.TypeObject ... ... End

I also often test my application by looking at all the runtime objects in the debugger before quitting the application (to see if there are memory leaks). Just because of one Xojo.Core.Introspection call this is nearly impossible because introspection creates TypeInfos for the whole application and caches them. Last year I filed a feature request for this (35899 - Introspection: Ability to clear the cache).

Back in beta last year, Joe Ranieri explained that Introspection was providing the type. Implied was that a special property was not necessary. Maybe the benchmark Jeremy conducted will engage him to reconsider.

I did that months ago. The introspection overhead is causing a lot of trouble.
We do want to have select case mit integer types like variant for the speed. Especially I don’t want to have temp objects created and tons of string comparisons for each variant. Especially if you do something in a loop a 1000 times.

Given the comparative slowness of using introspection to get Auto type, maybe Joe could elaborate on the reasons behind not providing a faster type property.

I wonder if part of it may be to discourage the use of Auto’s when not absolutely necessary?

  • Karen

[quote=186269:@Karen Atkocius]Given the comparative slowness of using introspection to get Auto type, maybe Joe could elaborate on the reasons behind not providing a faster type property.

I wonder if part of it may be to discourage the use of Auto’s when not absolutely necessary?

  • Karen[/quote]

Then discourage dictionary as well…

Because an integer property can’t tell you enough. With variant, should type return TypeDate or TypeObject for a Date? Both are true. Obviously, it should return TypeDate, but that implies it is not an object.

Arrays are a mess too. An integer just can’t give you the details effectively.

It does. This part of the Variant data type worked very well.

In the end what we all will do is have an Extends method on Auto mimicking Variant.Type in a very long – and slow – Select statement – while the compiler knows and could provide the type in an easy way.

I am very much in favor of the new framework and its increased type safety (and also the increase of encoding safety on Text compared to String). But not having Auto.Type is bad. The issues with Variants were the implicit conversions, not that you could interrogate the variable about its type.

The example for Date is the one exception, and it is mentioned in the docs and probably never posed a problem to anybody, as it shows in autocomplete.

I agree with Eli. The Type property is not comprehensive, but Introspection and IsA are available when more detail is needed.

If Xojo were to implement Auto.Type and do away with TypeDate so a Date would simply read as Object, I’d be fine with that. I wouldn’t mind code that looked like:

if a.Type = Auto.TypeObject and ( a IsA Xojo.Core.Date or a IsA Global.Date ) then…

Would it not be possible to write a class that wraps Auto and provides the type functionality of variant? Something like this (on mobile so sorry for any typos):

Class BetterAuto
Private value as Auto
Public Type as VarTypes

Public enum VarTypes
TypeInteger
TypeLong
TypeObject
//etc you get the idea

Function Operator_Convert() as Auto
Return value
End function

Sub Operator_Convert(inVal as Integer)
Value = inVal
Type = VarTypes.TypeInteger
End Sub

//more operator converts for each varType

Then you wouldn’t need introspection anymore so determining the type will be faster. Just an idea I had after reading this discussion. Maybe someone wants to make the class?

Sure, but you then have more memory overhead which is one of the benefits of Auto as I understand it and also more cumbersome to use with API expecting Auto’s or returning Autos.

Edit (Paul): Fixed quote tags

But then you can stay with Variants. I like the type safety which comes with Auto. I would never write an Extension method with Operator_Convert on Auto as this re-introduces the problems we have all faced with Variants.

[quote=186307:@Jeremy Cowgar]
Sure, but you then have more memory overhead which is one of the benefits of Auto as I understand it and also more cumbersome to use with API expecting Auto’s or returning Autos.[/quote]
Well I don’t see a huge memory overhead since you are only adding one property for the type which has a negligible impact on memory, especially in today’s computers. The beauty of operator convert is the class will automagically convert to Auto just by passing an instance of the class into a method which expects type auto, and will automagically convert from any other type (integer, Text, object, etc) when it is assigned to the variable. Of course there is still the case where the method returns an Auto, but you should be able to change those methods to return an explicit type, in which case it wouldn’t be a problem, or we could have an operator convert or constructor which accepts a variable of type auto and then uses the select case mentioned above to determine the type only in that case.

I don’t think his proposed class would. It doesn’t do any automatic conversion. It stores the value as is into an Auto, but while storing it, it is able to use the method type (via overloading) to set an additional .Type property. So, his class would still have the type safety but provide a .Type property to look at to see what type of Auto it contains.

The problem would be in actual use with the existing API and also the fact that you are now introducing classes to manage things which takes away from the memory efficiency of Auto.

It’s certainly a move in the right direction, but the best solution would be a .Type property on the Auto itself from Xojo.

I completely agree with you. But until we get that (if we get that) then we will have to make do with something like that class or the continued use of long and slow select case statements.

I guess my question is, are we going to get better type determination with Auto?

Only @Joe Ranieri can answer that. That’s assuming he’s allowed to answer because it might give away some long term plan. At XDC I heard a couple of comments that lead me to believe Auto is going to get way more useful in the future.