Skip to content

Optimizations #153

Open
Open
@Carterpersall

Description

This will be where I keep track of the improvements to Winfetch I make in various pull requests

How I achieve my speed improvements:

  • Assume anything CIM and WMI will be slow and avoid it like the devil
  • Piping is slow, so avoid using it when possible (do $e.Name instead of $e | Select-Object Name)
  • Use https://github.com/nohwnd/Profiler and import generated JSON files into https://www.speedscope.app/ or view results directly in PowerShell
    • Shows which functions take the longest, but not what operations within the function take the longest. That takes looking into the function yourself and heavily leveraging Measure-Command
  • I downclock my laptop hard (1.06 GHz) to get more battery life out of it. But what ends up happening with PowerShell is that slow operations take a very long time to execute, making speed differences much more noticeable
  • Use preexisting values wherever possible
  • Google things a lot. Even if you think you know how to do something fast, there may be a faster or easier solution out there
  • Always investigate using a .NET library instead of a PowerShell command or CIM/WMI call, but don't assume that it will be faster
  • $null = operation > [void]operation > operation | Out-Null
  • Always check if $var | ForEach-Object or $variable.foreach() is faster
  • Check if using [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey() is faster than Get-ItemProperty.

Notes to self:

  • Keep an eye on the speed improvement of creating a CIM Instance
    • Currently negligible or faster in both slow and fast systems using both all functions and my personal config

TODO:

  • Improve the beginning of the script
    • Add more arguments
    • Perform checks for variables only used in some functions
      • Implementing for the initial CIM declaration leads to speed regression
        • Checks for config values need to be almost negligible to be worth it
    • Create more variables for commands used in multiple functions
    • More and faster environment checking
  • Improve the functions
    • info_ps_pkgs
    • info_pkgs
    • info_gpu
    • info_cpu_usage
    • info_locale
    • info_weather
    • info_local_ip
    • info_memory
      • Attempted to reverse engineer Get-CimInstance
        • Initially tried (([System.Management.ManagementObjectSearcher]::new(([System.Management.ObjectQuery]::new("SELECT TotalVisibleMemorySize,FreePhysicalMemory FROM Win32_OperatingSystem")))).Get())
          • ~10ms slower (30ms → 40ms)
        • Then tried $cimSession.GetInstance("root/cimv2","Win32_OperatingSystem").CimInstanceProperties
          • ~18ms slower (30ms → 48.6)
          • Slower because it isn't grabbing specific properties, instead it is grabbing all of them
          • I later found $cimSession.EnumerateInstances("root/cimv2","Win32_OperatingSystem") which does the same thing but at about half the speed
        • After diving into how Get-CimInstance worked, I made $cimSession.QueryInstances("root/cimv2","WQL","SELECT TotalVisibleMemorySize,FreePhysicalMemory FROM Win32_OperatingSystem")
          • ~10ms slower (30 → 40ms)
          • The weird thing with this one is that this should be almost exactly what Get-CimInstance uses, except that it uses CimSession.QueryInstancesAsync() instead
        • Using my new knowledge of how Get-CimInstance worked, I then attempted to optimize the execution of the command
          • First tried defining the flags -QueryDialect WQL -Namespace root/cimv2 in an attempt to prevent the function from needing to retrieve it
            • Ended up decreasing speed extremely slightly
          • Then tried replacing the flags -ClassName Win32_OperatingSystem -Property TotalVisibleMemorySize,FreePhysicalMemory with -Query "SELECT TotalVisibleMemorySize,FreePhysicalMemory FROM Win32_OperatingSystem" to prevent the code from generating the query
            • Caused a very slight speed increase (<1ms)
          • Then I got curious and checked what the speed is when I removed -CimSession $cimSession
            • Ended up saving ~1ms somehow
            • Might not show this speed gain in the script though, as the reuse of the CimSession might be what it's missing here
  • Implement multithreading
  • Look into incorrect resolution being reported

Speed Improvement (Excluding Multithreading):
Before:

After (Subtracting Speed Gains):

  • 11444 ms
    • 63% Faster w. everything enabled

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions