Terminal-Icons
Terminal-Icons copied to clipboard
Possible improvements of load time
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 #13 are present.
- Operating System and PowerShell version:
pwsh
7.2.1 on a debian (installed vianix
);pwsh-7.2.2
on a win10 (installed from MS Store) Both machines are well-off dev machines
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]
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.
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...
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
@waingt That sounds like a good optimization (converting glyphs, themes, and color sequences to xml during the build process).
@waingt That's a great improvement! On my machine Terminal-Icons load time went from 1300ms to 470ms
Any plans to add this improvement?
Gentle ping=)
@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
any update ?
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:
@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.
@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.
@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
@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 (https://github.com/devblackops/Terminal-Icons/issues/76#issuecomment-1147675907).
@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!
@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.
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.