Skip to content
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

Possible improvements of load time #76

Open
ShrykeWindgrace opened this issue Apr 6, 2022 · 18 comments
Open

Possible improvements of load time #76

ShrykeWindgrace opened this issue Apr 6, 2022 · 18 comments
Assignees
Labels
enhancement New feature or request

Comments

@ShrykeWindgrace
Copy link

I noticed a couple of things with import time of this wonderful module:
On a debian machine I get half a second (TotalMilliseconds : 412.3335) for Import-Module Terminal-Icons in my $PROFILE. Same command on a windows machine report ~1s import time.

So, I've got a couple of questions:

  • Do you have an insight on the reason of such a difference of load time (x2)?
  • Can we further reduce load times? Say, we find a way to import existing xml files without rereading color theme and icon theme each time, and re-generate these xml's only upon explicit user call (I assume that color theme changes relatively rarely) - would that allow us to gain a significant amount of import time? Judging by the dump below, I am inclined to say yes, but I might not be taking something into account.

Cheers and thanks for the good work!

Here's the output of $trace = Trace-Script -ScriptBlock {Import-Module /nix/store/x4nsl5qaj4i38nrdy8qzkx597ha21dxx-Terminal-Icons-0.9.0/Terminal-Icons/0.9.0/Terminal-Icons.psd1 };$trace.AllLines | Format-Table

console dump
Percent HitCount Duration         Average          SelfDuration     SelfAverage      Name                                 Line Text
------- -------- --------         -------          ------------     -----------      ----                                 ---- ----
    100        3 00:00:00.4558292 00:00:00.1519431 00:00:00.0011815 00:00:00.0003938 cd767f82-914f-4658-900f-1af8848bfaff    1 {Import-Module /nix/store/x4nsl5qaj4i38nrdy8qzkx597ha21dxx-Terminal-Icons-0.9.0/Terminal-Icons/0.9.0/Termina…
  3.055        1 00:00:00.0139238 00:00:00.0139238 00:00:00.0139238 00:00:00.0139238 Terminal-Icons.psd1                     1 @{
  0.034        1 00:00:00.0001571 00:00:00.0001571 00:00:00.0001571 00:00:00.0001571 Terminal-Icons.psm1                  1144 $moduleRoot    = $PSScriptRoot
  9.431        1 00:00:00.0429906 00:00:00.0429906 00:00:00.0417988 00:00:00.0417988 Terminal-Icons.psm1                  1145 $glyphs        = . $moduleRoot/Data/glyphs.ps1
  0.127        1 00:00:00.0005770 00:00:00.0005770 00:00:00.0005770 00:00:00.0005770 Terminal-Icons.psm1                  1146 $escape        = [char]27
  0.107        1 00:00:00.0004870 00:00:00.0004870 00:00:00.0004870 00:00:00.0004870 Terminal-Icons.psm1                  1147 $colorReset    = "${escape}[0m"
  0.002        1 00:00:00.0000092 00:00:00.0000092 00:00:00.0000092 00:00:00.0000092 Terminal-Icons.psm1                  1148 $defaultTheme  = 'devblackops'
  8.891        1 00:00:00.0405275 00:00:00.0405275 00:00:00.0029284 00:00:00.0029284 Terminal-Icons.psm1                  1149 $userThemePath = Get-ThemeStoragePath
  0.004        1 00:00:00.0000175 00:00:00.0000175 00:00:00.0000175 00:00:00.0000175 Terminal-Icons.psm1                  1150 $userThemeData = @{
  0.002        1 00:00:00.0000071 00:00:00.0000071 00:00:00.0000071 00:00:00.0000071 Terminal-Icons.psm1                  1160 $colorSequences = @{}
 12.701        1 00:00:00.0578957 00:00:00.0578957 00:00:00.0005635 00:00:00.0005635 Terminal-Icons.psm1                  1161 $iconThemes     = Import-IconTheme
  9.116        1 00:00:00.0415548 00:00:00.0415548 00:00:00.0005767 00:00:00.0005767 Terminal-Icons.psm1                  1162 $colorThemes    = Import-ColorTheme
 26.476        1 00:00:00.1206831 00:00:00.1206831 00:00:00.0022422 00:00:00.0022422 Terminal-Icons.psm1                  1163 $colorThemes.GetEnumerator().ForEach({
  1.874        2 00:00:00.0085435 00:00:00.0042718 00:00:00.0033811 00:00:00.0016906 Terminal-Icons.psm1                  1168 $prefs = Import-Preferences
  0.258        1 00:00:00.0011783 00:00:00.0011783 00:00:00.0011783 00:00:00.0011783 Terminal-Icons.psm1                  1171 $userThemeData.CurrentIconTheme  = $prefs.CurrentIconTheme
  0.242        1 00:00:00.0011052 00:00:00.0011052 00:00:00.0011052 00:00:00.0011052 Terminal-Icons.psm1                  1172 $userThemeData.CurrentColorTheme = $prefs.CurrentColorTheme
  2.083        1 00:00:00.0094933 00:00:00.0094933 00:00:00.0017669 00:00:00.0017669 Terminal-Icons.psm1                  1176 (Get-ChildItem $userThemePath -Filter '*_icon.xml').ForEach({
 18.562        1 00:00:00.0846105 00:00:00.0846105 00:00:00.0017086 00:00:00.0017086 Terminal-Icons.psm1                  1180 (Get-ChildItem $userThemePath -Filter '*_color.xml').ForEach({
  0.082        1 00:00:00.0003717 00:00:00.0003717 00:00:00.0003344 00:00:00.0003344 Terminal-Icons.psm1                  1187 $colorThemes.GetEnumerator().ForEach({
  0.044        1 00:00:00.0001993 00:00:00.0001993 00:00:00.0001708 00:00:00.0001708 Terminal-Icons.psm1                  1190 $iconThemes.GetEnumerator().ForEach({
  2.363        1 00:00:00.0107692 00:00:00.0107692 00:00:00.0003624 00:00:00.0003624 Terminal-Icons.psm1                  1195 $userThemeData.Themes.Color.GetEnumerator().ForEach({
  0.921        1 00:00:00.0042001 00:00:00.0042001 00:00:00.0004601 00:00:00.0004601 Terminal-Icons.psm1                  1199 $userThemeData.Themes.Icon.GetEnumerator().ForEach({
  0.868        2 00:00:00.0039576 00:00:00.0019788 00:00:00.0018716 00:00:00.0009358 Terminal-Icons.psm1                  1204 Save-Preferences -Preferences $prefs
  2.498        1 00:00:00.0113886 00:00:00.0113886 00:00:00.0113886 00:00:00.0113886 Terminal-Icons.psm1                  1208 Update-FormatData -Prepend ([IO.Path]::Combine($moduleRoot, 'Terminal-Icons.format.ps1xml'))
  0.261        1 00:00:00.0011918 00:00:00.0011918 00:00:00.0011918 00:00:00.0011918 glyphs.ps1                              1 @{
  0.007        3 00:00:00.0000321 00:00:00.0000107 00:00:00.0000321 00:00:00.0000107 Terminal-Icons.psm1                   166 function Get-ThemeStoragePath {
  0.008        3 00:00:00.0000382 00:00:00.0000127 00:00:00.0000382 00:00:00.0000127 Terminal-Icons.psm1                   171 if ($IsLinux -or $IsMacOs) {
  0.249        6 00:00:00.0011342 00:00:00.0001890 00:00:00.0011342 00:00:00.0001890 Terminal-Icons.psm1                   172 if (-not ($basePath = $env:XDG_CONFIG_HOME)) {
  0.158        3 00:00:00.0007196 00:00:00.0002399 00:00:00.0007196 00:00:00.0002399 Terminal-Icons.psm1                   181 if ($basePath) {
  0.348        3 00:00:00.0015852 00:00:00.0005284 00:00:00.0015852 00:00:00.0005284 Terminal-Icons.psm1                   182 $storagePath = [IO.Path]::Combine($basePath, 'powershell', 'Community', 'Terminal-Icons')
  7.783        3 00:00:00.0354779 00:00:00.0118260 00:00:00.0354779 00:00:00.0118260 Terminal-Icons.psm1                   183 if (-not (Test-Path $storagePath)) {
  0.011        3 00:00:00.0000501 00:00:00.0000167 00:00:00.0000501 00:00:00.0000167 Terminal-Icons.psm1                   186 $storagePath
  0.371        3 00:00:00.0016907 00:00:00.0005636 00:00:00.0016907 00:00:00.0005636 Terminal-Icons.psm1                   188 }
  0.002        1 00:00:00.0000073 00:00:00.0000073 00:00:00.0000073 00:00:00.0000073 Terminal-Icons.psm1                   203 function Import-IconTheme {
  0.003        1 00:00:00.0000134 00:00:00.0000134 00:00:00.0000134 00:00:00.0000134 Terminal-Icons.psm1                   208 $hash = @{}
 12.474        1 00:00:00.0568603 00:00:00.0568603 00:00:00.0461060 00:00:00.0461060 Terminal-Icons.psm1                   209 (Get-ChildItem -Path $moduleRoot/Data/iconThemes).ForEach({
   0.08        1 00:00:00.0003646 00:00:00.0003646 00:00:00.0003646 00:00:00.0003646 Terminal-Icons.psm1                   212 $hash
  0.019        1 00:00:00.0000866 00:00:00.0000866 00:00:00.0000866 00:00:00.0000866 Terminal-Icons.psm1                   213 }
  0.003        1 00:00:00.0000137 00:00:00.0000137 00:00:00.0000137 00:00:00.0000137 Terminal-Icons.psm1                   209 {
  2.242        1 00:00:00.0102202 00:00:00.0102202 00:00:00.0102202 00:00:00.0102202 Terminal-Icons.psm1                   210 $hash.Add($_.Basename, (Import-PowerShellDataFile $_.FullName))
  0.114        1 00:00:00.0005204 00:00:00.0005204 00:00:00.0005204 00:00:00.0005204 Terminal-Icons.psm1                   211 }
  0.003        1 00:00:00.0000118 00:00:00.0000118 00:00:00.0000118 00:00:00.0000118 Terminal-Icons.psm1                   189 function Import-ColorTheme {
  0.003        1 00:00:00.0000155 00:00:00.0000155 00:00:00.0000155 00:00:00.0000155 Terminal-Icons.psm1                   194 $hash = @{}
  8.966        1 00:00:00.0408707 00:00:00.0408707 00:00:00.0326197 00:00:00.0326197 Terminal-Icons.psm1                   195 (Get-ChildItem -Path $moduleRoot/Data/colorThemes).ForEach({
  0.002        1 00:00:00.0000109 00:00:00.0000109 00:00:00.0000109 00:00:00.0000109 Terminal-Icons.psm1                   201 $hash
  0.015        1 00:00:00.0000692 00:00:00.0000692 00:00:00.0000692 00:00:00.0000692 Terminal-Icons.psm1                   202 }
  0.002        1 00:00:00.0000074 00:00:00.0000074 00:00:00.0000074 00:00:00.0000074 Terminal-Icons.psm1                   195 {
  0.453        1 00:00:00.0020642 00:00:00.0020642 00:00:00.0020642 00:00:00.0020642 Terminal-Icons.psm1                   196 $colorData = Import-PowerShellDataFile $_.FullName
  0.523        1 00:00:00.0023853 00:00:00.0023853 00:00:00.0023853 00:00:00.0023853 Terminal-Icons.psm1                   197 $hash[$colorData.Name] = $colorData
  0.681        1 00:00:00.0031039 00:00:00.0031039 00:00:00.0031039 00:00:00.0031039 Terminal-Icons.psm1                   198 $hash[$colorData.Name].Types.Directories[''] = $colorReset
  0.146        1 00:00:00.0006667 00:00:00.0006667 00:00:00.0006667 00:00:00.0006667 Terminal-Icons.psm1                   199 $hash[$colorData.Name].Types.Files['']       = $colorReset
  0.005        1 00:00:00.0000235 00:00:00.0000235 00:00:00.0000235 00:00:00.0000235 Terminal-Icons.psm1                   200 }
  0.001        1 00:00:00.0000060 00:00:00.0000060 00:00:00.0000060 00:00:00.0000060 Terminal-Icons.psm1                  1163 {
 25.978        1 00:00:00.1184134 00:00:00.1184134 00:00:00.0019178 00:00:00.0019178 Terminal-Icons.psm1                  1164 $colorSequences[$_.Name] = ConvertTo-ColorSequence -ColorData $_.Value
  0.005        1 00:00:00.0000215 00:00:00.0000215 00:00:00.0000215 00:00:00.0000215 Terminal-Icons.psm1                  1165 }
  0.003        2 00:00:00.0000150 00:00:00.0000075 00:00:00.0000150 00:00:00.0000075 Terminal-Icons.psm1                   132 process {
  0.491        2 00:00:00.0022359 00:00:00.0011180 00:00:00.0021205 00:00:00.0010602 Terminal-Icons.psm1                   133 $cs      = New-EmptyColorTheme
  0.281        2 00:00:00.0012805 00:00:00.0006402 00:00:00.0012805 00:00:00.0006402 Terminal-Icons.psm1                   134 $cs.Name = $ColorData.Name
   0.62        2 00:00:00.0028241 00:00:00.0014120 00:00:00.0028241 00:00:00.0014120 Terminal-Icons.psm1                   137 if ($ColorData.Types.Directories['symlink']) {
  1.657        2 00:00:00.0075518 00:00:00.0037759 00:00:00.0016133 00:00:00.0008066 Terminal-Icons.psm1                   138 $cs.Types.Directories['symlink']  = ConvertFrom-RGBColor -RGB $ColorData.Types.Directories['symlink']
  0.008        2 00:00:00.0000349 00:00:00.0000174 00:00:00.0000349 00:00:00.0000174 Terminal-Icons.psm1                   140 if ($ColorData.Types.Directories['junction']) {
  0.091        2 00:00:00.0004149 00:00:00.0002074 00:00:00.0002400 00:00:00.0001200 Terminal-Icons.psm1                   141 $cs.Types.Directories['junction'] = ConvertFrom-RGBColor -RGB $ColorData.Types.Directories['junction']
  5.286        2 00:00:00.0240972 00:00:00.0120486 00:00:00.0024481 00:00:00.0012240 Terminal-Icons.psm1                   143 $ColorData.Types.Directories.WellKnown.GetEnumerator().ForEach({
  0.205        2 00:00:00.0009349 00:00:00.0004674 00:00:00.0009349 00:00:00.0004674 Terminal-Icons.psm1                   148 if ($ColorData.Types.Files['symlink']) {
  0.088        2 00:00:00.0003989 00:00:00.0001994 00:00:00.0002298 00:00:00.0001149 Terminal-Icons.psm1                   149 $cs.Types.Files['symlink']  = ConvertFrom-RGBColor -RGB $ColorData.Types.Files['symlink']
  0.006        2 00:00:00.0000270 00:00:00.0000135 00:00:00.0000270 00:00:00.0000135 Terminal-Icons.psm1                   151 if ($ColorData.Types.Files['junction']) {
  0.076        2 00:00:00.0003466 00:00:00.0001733 00:00:00.0001815 00:00:00.0000908 Terminal-Icons.psm1                   152 $cs.Types.Files['junction'] = ConvertFrom-RGBColor -RGB $ColorData.Types.Files['junction']
  6.692        2 00:00:00.0305056 00:00:00.0152528 00:00:00.0003742 00:00:00.0001871 Terminal-Icons.psm1                   154 $ColorData.Types.Files.WellKnown.GetEnumerator().ForEach({
 27.401        2 00:00:00.1249035 00:00:00.0624518 00:00:00.0010738 00:00:00.0005369 Terminal-Icons.psm1                   159 $ColorData.Types.Files.GetEnumerator().Where({$_.Name -ne 'WellKnown' -and $_.Name -ne ''}).ForEach({
  0.004        2 00:00:00.0000196 00:00:00.0000098 00:00:00.0000196 00:00:00.0000098 Terminal-Icons.psm1                   163 $cs
  0.204        2 00:00:00.0009316 00:00:00.0004658 00:00:00.0009316 00:00:00.0004658 Terminal-Icons.psm1                   164 }
  0.002        2 00:00:00.0000097 00:00:00.0000048 00:00:00.0000097 00:00:00.0000048 Terminal-Icons.psm1                   245 function New-EmptyColorTheme {
  0.007        2 00:00:00.0000310 00:00:00.0000155 00:00:00.0000310 00:00:00.0000155 Terminal-Icons.psm1                   251 @{
  0.016        2 00:00:00.0000747 00:00:00.0000374 00:00:00.0000747 00:00:00.0000374 Terminal-Icons.psm1                   268 }
   0.74      780 00:00:00.0033748 00:00:00.0000043 00:00:00.0033748 00:00:00.0000043 Terminal-Icons.psm1                   116 process {
  1.714      780 00:00:00.0078151 00:00:00.0000100 00:00:00.0078151 00:00:00.0000100 Terminal-Icons.psm1                   117 $RGB = $RGB.Replace('#', '')
  3.203      780 00:00:00.0146011 00:00:00.0000187 00:00:00.0146011 00:00:00.0000187 Terminal-Icons.psm1                   118 $r   = [convert]::ToInt32($RGB.SubString(0,2), 16)
  1.066      780 00:00:00.0048576 00:00:00.0000062 00:00:00.0048576 00:00:00.0000062 Terminal-Icons.psm1                   119 $g   = [convert]::ToInt32($RGB.SubString(2,2), 16)
  1.038      780 00:00:00.0047293 00:00:00.0000061 00:00:00.0047293 00:00:00.0000061 Terminal-Icons.psm1                   120 $b   = [convert]::ToInt32($RGB.SubString(4,2), 16)
  1.736      780 00:00:00.0079142 00:00:00.0000101 00:00:00.0079142 00:00:00.0000101 Terminal-Icons.psm1                   122 "${script:escape}[38;2;$r;$g;$b`m"
  9.982      780 00:00:00.0455019 00:00:00.0000583 00:00:00.0455019 00:00:00.0000583 Terminal-Icons.psm1                   123 }
  0.062       80 00:00:00.0002845 00:00:00.0000036 00:00:00.0002845 00:00:00.0000036 Terminal-Icons.psm1                   143 {
  4.383       80 00:00:00.0199800 00:00:00.0002498 00:00:00.0080415 00:00:00.0001005 Terminal-Icons.psm1                   144 $cs.Types.Directories[$_.Name] = ConvertFrom-RGBColor -RGB $_.Value
  0.304       80 00:00:00.0013846 00:00:00.0000173 00:00:00.0013846 00:00:00.0000173 Terminal-Icons.psm1                   145 }
  0.113      148 00:00:00.0005156 00:00:00.0000035 00:00:00.0005156 00:00:00.0000035 Terminal-Icons.psm1                   154 {
  4.707      148 00:00:00.0214545 00:00:00.0001450 00:00:00.0106498 00:00:00.0000720 Terminal-Icons.psm1                   155 $cs.Types.Files.WellKnown[$_.Name] = ConvertFrom-RGBColor -RGB $_.Value
   1.79      148 00:00:00.0081613 00:00:00.0000551 00:00:00.0081613 00:00:00.0000551 Terminal-Icons.psm1                   156 }
   3.37     1644 00:00:00.0153595 00:00:00.0000093 00:00:00.0153595 00:00:00.0000093 Terminal-Icons.psm1                   159 {$_.Name -ne 'WellKnown' -and $_.Name -ne ''}
  0.391      544 00:00:00.0017823 00:00:00.0000033 00:00:00.0017823 00:00:00.0000033 Terminal-Icons.psm1                   159 {
 21.636      544 00:00:00.0986233 00:00:00.0001813 00:00:00.0390201 00:00:00.0000717 Terminal-Icons.psm1                   160 $cs.Types.Files[$_.Name] = ConvertFrom-RGBColor -RGB $_.Value
  1.769      544 00:00:00.0080646 00:00:00.0000148 00:00:00.0080646 00:00:00.0000148 Terminal-Icons.psm1                   161 }
  0.001        1 00:00:00.0000061 00:00:00.0000061 00:00:00.0000061 00:00:00.0000061 Terminal-Icons.psm1                   225 begin {
  0.005        1 00:00:00.0000216 00:00:00.0000216 00:00:00.0000216 00:00:00.0000216 Terminal-Icons.psm1                   226 $defaultPrefs = @{
  0.003        1 00:00:00.0000138 00:00:00.0000138 00:00:00.0000138 00:00:00.0000138 Terminal-Icons.psm1                   230 }
  0.001        1 00:00:00.0000067 00:00:00.0000067 00:00:00.0000067 00:00:00.0000067 Terminal-Icons.psm1                   232 process {
  0.288        1 00:00:00.0013107 00:00:00.0013107 00:00:00.0013107 00:00:00.0013107 Terminal-Icons.psm1                   233 if (Test-Path $Path) {
  0.326        1 00:00:00.0014866 00:00:00.0014866 00:00:00.0014866 00:00:00.0014866 Terminal-Icons.psm1                   235 Import-Clixml -Path $Path -ErrorAction Stop
  0.009        1 00:00:00.0000414 00:00:00.0000414 00:00:00.0000414 00:00:00.0000414 Terminal-Icons.psm1                   243 }
  0.001        1 00:00:00.0000066 00:00:00.0000066 00:00:00.0000066 00:00:00.0000066 Terminal-Icons.psm1                  1176 {
  1.192        1 00:00:00.0054335 00:00:00.0054335 00:00:00.0054335 00:00:00.0054335 Terminal-Icons.psm1                  1177 $userIconTheme = Import-CliXml -Path $_.FullName
  0.497        1 00:00:00.0022647 00:00:00.0022647 00:00:00.0022647 00:00:00.0022647 Terminal-Icons.psm1                  1178 $userThemeData.Themes.Icon[$userIconTheme.Name] = $userIconTheme
  0.005        1 00:00:00.0000216 00:00:00.0000216 00:00:00.0000216 00:00:00.0000216 Terminal-Icons.psm1                  1179 }
  0.002        1 00:00:00.0000070 00:00:00.0000070 00:00:00.0000070 00:00:00.0000070 Terminal-Icons.psm1                  1180 {
  0.421        1 00:00:00.0019182 00:00:00.0019182 00:00:00.0019182 00:00:00.0019182 Terminal-Icons.psm1                  1181 $userColorTheme = Import-CliXml -Path $_.FullName
  0.174        1 00:00:00.0007941 00:00:00.0007941 00:00:00.0007941 00:00:00.0007941 Terminal-Icons.psm1                  1182 $userThemeData.Themes.Color[$userColorTheme.Name] = $userColorTheme
 17.588        1 00:00:00.0801729 00:00:00.0801729 00:00:00.0001465 00:00:00.0001465 Terminal-Icons.psm1                  1183 $colorSequences[$userColorTheme.Name] = ConvertTo-ColorSequence -ColorData $userThemeData.Themes.Color[$user…
  0.002        1 00:00:00.0000097 00:00:00.0000097 00:00:00.0000097 00:00:00.0000097 Terminal-Icons.psm1                  1184 }
  0.001        1 00:00:00.0000059 00:00:00.0000059 00:00:00.0000059 00:00:00.0000059 Terminal-Icons.psm1                  1187 {
  0.005        1 00:00:00.0000206 00:00:00.0000206 00:00:00.0000206 00:00:00.0000206 Terminal-Icons.psm1                  1188 $userThemeData.Themes.Color[$_.Name] = $_.Value
  0.002        1 00:00:00.0000108 00:00:00.0000108 00:00:00.0000108 00:00:00.0000108 Terminal-Icons.psm1                  1189 }
  0.001        1 00:00:00.0000048 00:00:00.0000048 00:00:00.0000048 00:00:00.0000048 Terminal-Icons.psm1                  1190 {
  0.003        1 00:00:00.0000156 00:00:00.0000156 00:00:00.0000156 00:00:00.0000156 Terminal-Icons.psm1                  1191 $userThemeData.Themes.Icon[$_.Name] = $_.Value
  0.002        1 00:00:00.0000081 00:00:00.0000081 00:00:00.0000081 00:00:00.0000081 Terminal-Icons.psm1                  1192 }
  0.001        1 00:00:00.0000065 00:00:00.0000065 00:00:00.0000065 00:00:00.0000065 Terminal-Icons.psm1                  1195 {
  0.057        2 00:00:00.0002596 00:00:00.0001298 00:00:00.0002596 00:00:00.0001298 Terminal-Icons.psm1                  1196 $colorThemePath = Join-Path $userThemePath "$($_.Name)_color.xml"
   2.22        1 00:00:00.0101184 00:00:00.0101184 00:00:00.0101184 00:00:00.0101184 Terminal-Icons.psm1                  1197 $_.Value | Export-Clixml -Path $colorThemePath -Force
  0.005        1 00:00:00.0000223 00:00:00.0000223 00:00:00.0000223 00:00:00.0000223 Terminal-Icons.psm1                  1198 }
  0.001        1 00:00:00.0000064 00:00:00.0000064 00:00:00.0000064 00:00:00.0000064 Terminal-Icons.psm1                  1199 {
  0.048        2 00:00:00.0002193 00:00:00.0001096 00:00:00.0002193 00:00:00.0001096 Terminal-Icons.psm1                  1200 $iconThemePath = Join-Path $userThemePath "$($_.Name)_icon.xml"
  0.767        1 00:00:00.0034981 00:00:00.0034981 00:00:00.0034981 00:00:00.0034981 Terminal-Icons.psm1                  1201 $_.Value | Export-Clixml -Path $iconThemePath -Force
  0.004        1 00:00:00.0000162 00:00:00.0000162 00:00:00.0000162 00:00:00.0000162 Terminal-Icons.psm1                  1202 }
  0.001        1 00:00:00.0000067 00:00:00.0000067 00:00:00.0000067 00:00:00.0000067 Terminal-Icons.psm1                   410 process {
  0.178        1 00:00:00.0008099 00:00:00.0008099 00:00:00.0008099 00:00:00.0008099 Terminal-Icons.psm1                   411 Write-Debug ('Saving preferendces to [{0}]' -f $Path)
  0.086        1 00:00:00.0003900 00:00:00.0003900 00:00:00.0003900 00:00:00.0003900 Terminal-Icons.psm1                   412 $Preferences | Export-CliXml -Path $Path -Force
  0.006        1 00:00:00.0000260 00:00:00.0000260 00:00:00.0000260 00:00:00.0000260 Terminal-Icons.psm1                   413 }

Context

I am trying to reduce the load time of a new pwsh instance. Measure-Command {Import-Module Terminal-Icons} proves to be one of slow points of my $PROFILE.

Your Environment

  • Module version used: Terminal-Icons-0.9.0 from PSGallery, so the fixes from Slow import #13 are present.
  • Operating System and PowerShell version:
    pwsh 7.2.1 on a debian (installed via nix); pwsh-7.2.2 on a win10 (installed from MS Store)
    Both machines are well-off dev machines
@devblackops devblackops self-assigned this Apr 7, 2022
@devblackops devblackops added the enhancement New feature or request label Apr 7, 2022
@devblackops
Copy link
Owner

Thanks for the issue @ShrykeWindgrace. One possible enhancement would be to optimize how the RGB colors from the theme are converted to escape sequences. When a theme is loaded, it calls an internal function (ConvertFrom-RGBColor) for each color in the theme, so will be executed hundreds of times. I'm sure we can make that better.

Percent HitCount Duration         Average          SelfDuration     SelfAverage      Name                                 Line Text
------- -------- --------         -------          ------------     -----------      ----                                 ---- ----
    100        3 00:00:00.1573740 00:00:00.0524580 00:00:00.0021095 00:00:00.0007032 442b3f47-f976-43af-96a0-4e7f5198a1f6    1 {import-module terminal-icons}
 30.545        1 00:00:00.0480701 00:00:00.0480701 00:00:00.0480701 00:00:00.0480701 Terminal-Icons.psm1                  1208 Update-FormatData -Prepend ([IO.Path]::Combine($moduleRoot, 'Terminal-Icons.format.ps1xml'))
 25.446        2 00:00:00.0400450 00:00:00.0200225 00:00:00.0000279 00:00:00.0000140 Terminal-Icons.psm1                   159 $ColorData.Types.Files.GetEnumerator().Where({$_.Name -ne 'WellKnown' -and $_.Name -ne ''}).ForEach({…
 21.729        1 00:00:00.0341959 00:00:00.0341959 00:00:00.0034830 00:00:00.0034830 Terminal-Icons.psm1                  1180 (Get-ChildItem $userThemePath -Filter '*_color.xml').ForEach({…
   19.6      544 00:00:00.0308446 00:00:00.0000567 00:00:00.0176657 00:00:00.0000325 Terminal-Icons.psm1                   160 $cs.Types.Files[$_.Name] = ConvertFrom-RGBColor -RGB $_.Value
 18.855        1 00:00:00.0296728 00:00:00.0296728 00:00:00.0000447 00:00:00.0000447 Terminal-Icons.psm1                  1183 $colorSequences[$userColorTheme.Name] = ConvertTo-ColorSequence -ColorData $userThemeData.Themes.Color[$userColorTheme.Name]

@cdonnellytx
Copy link

One optimization I have found is to lazy-load the glyphs until they are actually used (i.e., calling Get-ChildItem). This cuts load time on my machine by about half (wall clock ~600ms -> ~300ms), although it means the first call to Get-ChildItem will be slower.

I also tried folding the glyph data into the .psm1 file, but that made things objectively worse (~750ms on average), mostly spent by PowerShell loading the now-270kB .psm1 file.

@ShrykeWindgrace
Copy link
Author

That's a good idea =)

... mostly spent by PowerShell loading the now-270kB .psm1 file.

This part of powershell I truly do not understand. We have top of line CPUs, SSDs with astronomical read speeds, 32Gb RAM, yet reading a 270Kb file takes about a second...

@waingt
Copy link

waingt commented Jun 6, 2022

Idea

I'm not really sure about the data convertion from .ps1(1 file) + .psd1(2 files) + .xml(2 files) -> hashtable -> .xml(2 files)
Could we utilize the highly optimized Import-Clixml Export-Clixml to serialize data in only one file?
The main idea is to minimize the expensive IO and data conversion operations

Implement

First, I did $userThemeData,$colorSequences,$glyphs|Export-Clixml -Path "$moduleRoot/Data/Data.xml" in Terminal-Icons.psm1
I suggest distributing that Data.xml with the module instead of *.ps(d)1
Then, I modified Terminal-Icons.psm1 as:

$moduleRoot    = $PSScriptRoot
# $glyphs        = . $moduleRoot/Data/glyphs.ps1
$escape        = [char]27
$colorReset    = "${escape}[0m"
$defaultTheme  = 'devblackops'
$userThemePath = Get-ThemeStoragePath
# Load or create default prefs
$prefs = Import-Preferences
$userThemeData,$colorSequences,$glyphs =Import-Clixml -Path "$moduleRoot/Data/Data.xml"
# Save-Preferences -Preferences $prefs
Update-FormatData -Prepend ([IO.Path]::Combine($moduleRoot, 'Terminal-Icons.format.ps1xml'))

Import-Preferences.ps1:

function Import-Preferences {
    param(
        [parameter(ValueFromPipeline)]
        [string]$Path = (Join-Path (Get-ThemeStoragePath) 'prefs.xml'),
        [string]$DefaultThemeName = $script:defaultTheme
    )
    $defaultPrefs = @{
        CurrentColorTheme = $DefaultThemeName
        CurrentIconTheme  = $DefaultThemeName
    }
    if (Test-Path $Path) {
        try {
            Import-Clixml -Path $Path -ErrorAction Stop
        } catch {
            Write-Warning "Unable to parse [$Path]. Setting default preferences."
            $defaultPrefs
        }
    } else {
        Save-Preferences -Preferences $defaultPrefs # only need to save prefs if xml not exist
        $defaultPrefs
    }
}

So there is only two read operations in most cases

Result

Before:

pwsh -nop -c '(Measure-Command { Import-Module Terminal-Icons }).TotalMilliseconds'
422.9141
powershell -nop -c '(Measure-Command { Import-Module Terminal-Icons }).TotalMilliseconds'
525.8701

After:

pwsh -nop -c '(Measure-Command { Import-Module Terminal-Icons }).TotalMilliseconds'
175.0907
powershell -nop -c '(Measure-Command { Import-Module Terminal-Icons }).TotalMilliseconds'
175.3323

@devblackops
Copy link
Owner

@waingt That sounds like a good optimization (converting glyphs, themes, and color sequences to xml during the build process).

@ShrykeWindgrace
Copy link
Author

@waingt That's a great improvement! On my machine Terminal-Icons load time went from 1300ms to 470ms

@Roald87
Copy link

Roald87 commented Nov 13, 2022

Any plans to add this improvement?

@ShrykeWindgrace
Copy link
Author

Gentle ping=)

@TheThingy
Copy link

@waingt that is just amazing, you have saved what little sanity I have left

Here are my results

Before:

pwsh -nop -c '(Measure-Command { Import-Module Terminal-Icons }).TotalMilliseconds'
1120.7058

After:

pwsh -nop -c '(Measure-Command { Import-Module Terminal-Icons }).TotalMilliseconds'
143.5407

Again great work, and thanks

@lost22git
Copy link

any update ?

@ctolkien
Copy link

Just going to say, I have now idea how you guys are getting load times of even 1000ms, I'm at about 2800ms. This is on a beefy machine with SSDS, so I'm not sure what is causing the additional slowness:

image

@ChristopherHaws
Copy link

@ctolkien I has this issue before as well and I realized that the cause was One Drive was "clearing disk space" by keeping my modules in the cloud so they had to be downloaded to be used. Right clicking the folder and selecting "Keep available offline" helped bring it from ~4s to ~1s load times.

@ctolkien
Copy link

@ChristopherHaws these are on OneDrive but they are still local. I notice that everytime this module is instantiated, it writes the files back to disk, which is also going to be slow.

@ctolkien
Copy link

@ChristopherHaws so I ensured that OneDrive kept those files local and it got worse:

Now nearly 4 seconds:
00:03.7153552 Import-Module -Name Terminal-Icons

@ShrykeWindgrace
Copy link
Author

@ctolkien The daemon for OneDrive could be actively monitoring what happens with the files. So, if I were you, I would try two things:

  • move modules to a folder that OneDrive (nor any other automatic cloud backup) does not track at all and check load times. If they become reasonable, then you you have your culprit.
  • try to apply the patch/workaround by @waingt (Possible improvements of load time #76 (comment)).

@ChristopherHaws
Copy link

@ShrykeWindgrace How can I move the modules? PowerShell automatically installs them in a folder than is backed by OneDrive? Is there a variable I can change to change the module folder search path?

Thanks!

@ctolkien
Copy link

ctolkien commented Jun 5, 2023

@ShrykeWindgrace / @ChristopherHaws

You can modify the $env:PSModulePath to set the directories where Powershell looks for modules.

I tried putting this on an entirely separate drive (of exactly the same type), not managed by OneDrive or other backup providers, and it appears to be about 100ms slower, but I've had some loads which are equally as fast, so doesn't conclusively make any difference - and definitely nothing noticeable.

I don't think it's OneDrive in this case. Will keep trying some of the other suggestions in this thread.

@nganjehloo
Copy link

nganjehloo commented Mar 25, 2024

Idea

I'm not really sure about the data convertion from .ps1(1 file) + .psd1(2 files) + .xml(2 files) -> hashtable -> .xml(2 files) Could we utilize the highly optimized Import-Clixml Export-Clixml to serialize data in only one file? The main idea is to minimize the expensive IO and data conversion operations

Implement

First, I did $userThemeData,$colorSequences,$glyphs|Export-Clixml -Path "$moduleRoot/Data/Data.xml" in Terminal-Icons.psm1 I suggest distributing that Data.xml with the module instead of *.ps(d)1 Then, I modified Terminal-Icons.psm1 as:

$moduleRoot    = $PSScriptRoot
# $glyphs        = . $moduleRoot/Data/glyphs.ps1
$escape        = [char]27
$colorReset    = "${escape}[0m"
$defaultTheme  = 'devblackops'
$userThemePath = Get-ThemeStoragePath
# Load or create default prefs
$prefs = Import-Preferences
$userThemeData,$colorSequences,$glyphs =Import-Clixml -Path "$moduleRoot/Data/Data.xml"
# Save-Preferences -Preferences $prefs
Update-FormatData -Prepend ([IO.Path]::Combine($moduleRoot, 'Terminal-Icons.format.ps1xml'))

Import-Preferences.ps1:

function Import-Preferences {
    param(
        [parameter(ValueFromPipeline)]
        [string]$Path = (Join-Path (Get-ThemeStoragePath) 'prefs.xml'),
        [string]$DefaultThemeName = $script:defaultTheme
    )
    $defaultPrefs = @{
        CurrentColorTheme = $DefaultThemeName
        CurrentIconTheme  = $DefaultThemeName
    }
    if (Test-Path $Path) {
        try {
            Import-Clixml -Path $Path -ErrorAction Stop
        } catch {
            Write-Warning "Unable to parse [$Path]. Setting default preferences."
            $defaultPrefs
        }
    } else {
        Save-Preferences -Preferences $defaultPrefs # only need to save prefs if xml not exist
        $defaultPrefs
    }
}

So there is only two read operations in most cases

Result

Before:

pwsh -nop -c '(Measure-Command { Import-Module Terminal-Icons }).TotalMilliseconds'
422.9141
powershell -nop -c '(Measure-Command { Import-Module Terminal-Icons }).TotalMilliseconds'
525.8701

After:

pwsh -nop -c '(Measure-Command { Import-Module Terminal-Icons }).TotalMilliseconds'
175.0907
powershell -nop -c '(Measure-Command { Import-Module Terminal-Icons }).TotalMilliseconds'
175.3323

I gave this a shot. It helped but only by about 50ms. I went from 480 to 430 on a i7-8750H. I imagine the sheer number of glyphs is the primary issue. Parsing XML is always gonna be slow. Most glyphs go unused so its probably a better idea to provide a tool that lets the user filter the glyphs by all the file types they've opened/encountered.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

10 participants