Search code examples
vb.netregistry

Is either of these VB.NET methods faster: SaveSetting() or SetValue()?


I update my app's metrics a lot in registry, and want to know which method of writing to system registry is significantly faster.


Solution

  • If you use a .NET decompiler to peek into the source code of the Interaction class/module under the Microsoft.VisualBasic namespace, you'll find that the SaveSetting() method actually uses SetValue() under the hood:*

    /// <summary>Saves or creates an application entry in the Windows registry. The My feature gives you greater productivity and performance in registry operations than SaveSetting. For more information, see <see cref="P:Microsoft.VisualBasic.Devices.ServerComputer.Registry" />.</summary>
    /// <param name="AppName">Required. String expression containing the name of the application or project to which the setting applies.</param>
    /// <param name="Section">Required. String expression containing the name of the section in which the key setting is being saved.</param>
    /// <param name="Key">Required. String expression containing the name of the key setting being saved.</param>
    /// <param name="Setting">Required. Expression containing the value to which <paramref name="Key" /> is being set.</param>
    /// <exception cref="T:System.ArgumentException">Key registry could not be created, or user is not logged in.</exception>
    /// <filterpriority>1</filterpriority>
    /// <PermissionSet>
    ///   <IPermission class="System.Security.Permissions.RegistryPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" />
    /// </PermissionSet>
    public static void SaveSetting(string AppName, string Section, string Key, string Setting)
    {
        Interaction.CheckPathComponent(AppName);
        Interaction.CheckPathComponent(Section);
        Interaction.CheckPathComponent(Key);
        string text = Interaction.FormRegKey(AppName, Section);
        RegistryKey registryKey = Registry.CurrentUser.CreateSubKey(text);
        if (registryKey == null)
        {
            throw new ArgumentException(Utils.GetResourceString("Interaction_ResKeyNotCreated1", new string[]
            {
                text
            }));
        }
        try
        {
            registryKey.SetValue(Key, Setting);
        }
        catch (Exception ex)
        {
            throw ex;
        }
        finally
        {
            registryKey.Close();
        }
    }
    

    Or in VB, if you prefer:

    ''' <summary>Saves or creates an application entry in the Windows registry. The My feature gives you greater productivity and performance in registry operations than SaveSetting. For more information, see <see cref="P:Microsoft.VisualBasic.Devices.ServerComputer.Registry" />.</summary>
    ''' <param name="AppName">Required. String expression containing the name of the application or project to which the setting applies.</param>
    ''' <param name="Section">Required. String expression containing the name of the section in which the key setting is being saved.</param>
    ''' <param name="Key">Required. String expression containing the name of the key setting being saved.</param>
    ''' <param name="Setting">Required. Expression containing the value to which <paramref name="Key" /> is being set.</param>
    ''' <exception cref="T:System.ArgumentException">Key registry could not be created, or user is not logged in.</exception>
    ''' <filterpriority>1</filterpriority>
    ''' <PermissionSet>
    '''   <IPermission class="System.Security.Permissions.RegistryPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" />
    ''' </PermissionSet>
    Public Sub SaveSetting(AppName As String, Section As String, Key As String, Setting As String)
        Interaction.CheckPathComponent(AppName)
        Interaction.CheckPathComponent(Section)
        Interaction.CheckPathComponent(Key)
        Dim text As String = Interaction.FormRegKey(AppName, Section)
        Dim registryKey As RegistryKey = Registry.CurrentUser.CreateSubKey(text)
        If registryKey Is Nothing Then
            Throw New ArgumentException(Utils.GetResourceString("Interaction_ResKeyNotCreated1", New String() { text }))
        End If
        Try
            registryKey.SetValue(Key, Setting)
        Catch ex As Exception
            Throw ex
        Finally
            registryKey.Close()
        End Try
    End Sub
    

    Therefore, I would expect them to have the same performance in this particular case (assuming you will be basically replicating the same behavior). However, the Microsoft.Win32.Registry class (or the My.Computer.Registry property, which is just a wrapper for the said class) is going to be more flexible and provides more options as noted in the documentation (thanks, Jimi!) and in the XML comments shown above.

    As to the performance, to be 100% certain (assuming you actually need to), then you should always measure.


    * This code was extracted using ILSpy.