Skip to content

Commit d582d9e

Browse files
perf(hotreload): Reduce the memory allocation
1 parent 779e773 commit d582d9e

File tree

7 files changed

+133
-87
lines changed

7 files changed

+133
-87
lines changed

build/Uno.WinUI.RemoteControl.nuspec

Lines changed: 62 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,101 +1,110 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
33
<metadata minClientVersion="5.0">
4-
<id>Uno.UI.RemoteControl</id>
5-
<version>0.1.0.0</version>
6-
<title>Uno.UI.RemoteControl</title>
7-
<authors>nventive</authors>
8-
<owners>nventive</owners>
9-
<requireLicenseAcceptance>false</requireLicenseAcceptance>
10-
<projectUrl>https://platform.uno/</projectUrl>
11-
<license type="expression">Apache-2.0</license>
12-
<iconUrl>https://nv-assets.azurewebsites.net/logos/uno.png</iconUrl>
13-
<description>Remote Control module for Uno Platform projects, such as XAML Hot Reload.</description>
14-
<copyright>Copyright (C) 2015-2019 nventive inc. - all rights reserved</copyright>
15-
<repository type="git" url="https://github.com/unoplatform/uno.git" branch="$branch$" commit="$commitid$" />
16-
17-
<dependencies>
4+
<id>Uno.UI.RemoteControl</id>
5+
<version>0.1.0.0</version>
6+
<title>Uno.UI.RemoteControl</title>
7+
<authors>nventive</authors>
8+
<owners>nventive</owners>
9+
<requireLicenseAcceptance>false</requireLicenseAcceptance>
10+
<projectUrl>https://platform.uno/</projectUrl>
11+
<license type="expression">Apache-2.0</license>
12+
<iconUrl>https://nv-assets.azurewebsites.net/logos/uno.png</iconUrl>
13+
<description>Remote Control module for Uno Platform projects, such as XAML Hot Reload.</description>
14+
<copyright>Copyright (C) 2015-2019 nventive inc. - all rights reserved</copyright>
15+
<repository type="git" url="https://github.com/unoplatform/uno.git" branch="$branch$" commit="$commitid$" />
16+
17+
<dependencies>
1818

1919
<!-- Android 9.0 -->
2020
<group targetFramework="MonoAndroid11.0">
2121
<dependency id="Uno.WinUI" version="1.29.0-dev.93" />
2222

2323
<dependency id="Newtonsoft.Json" version="12.0.2" />
24+
<dependency id="Microsoft.IO.RecyclableMemoryStream" version="2.1.3" />
2425
</group>
25-
26+
2627
<!-- Android 10.0 -->
2728
<group targetFramework="MonoAndroid10.0">
2829
<dependency id="Uno.WinUI" version="1.29.0-dev.93" />
2930

3031
<dependency id="Newtonsoft.Json" version="12.0.2" />
32+
<dependency id="Microsoft.IO.RecyclableMemoryStream" version="2.1.3" />
3133
</group>
3234

3335
<!-- iOS -->
34-
<group targetFramework="xamarinios10">
35-
<dependency id="Uno.WinUI" version="1.29.0-dev.93" />
36+
<group targetFramework="xamarinios10">
37+
<dependency id="Uno.WinUI" version="1.29.0-dev.93" />
3638

37-
<dependency id="Newtonsoft.Json" version="12.0.2" />
38-
</group>
39+
<dependency id="Newtonsoft.Json" version="12.0.2" />
40+
<dependency id="Microsoft.IO.RecyclableMemoryStream" version="2.1.3" />
41+
</group>
3942

40-
<!-- macOS -->
41-
<group targetFramework="xamarinmac20">
42-
<dependency id="Uno.WinUI" version="1.29.0-dev.93" />
43+
<!-- macOS -->
44+
<group targetFramework="xamarinmac20">
45+
<dependency id="Uno.WinUI" version="1.29.0-dev.93" />
4346

44-
<dependency id="Newtonsoft.Json" version="12.0.2" />
45-
</group>
47+
<dependency id="Newtonsoft.Json" version="12.0.2" />
48+
<dependency id="Microsoft.IO.RecyclableMemoryStream" version="2.1.3" />
49+
</group>
4650

4751
<!-- net6.0-ios -->
4852
<group targetFramework="net6.0-ios">
4953
<dependency id="Uno.WinUI" version="1.29.0-dev.93" />
5054

5155
<dependency id="Newtonsoft.Json" version="12.0.2" />
56+
<dependency id="Microsoft.IO.RecyclableMemoryStream" version="2.1.3" />
5257
</group>
5358

5459
<!-- net6.0-maccatalyst -->
5560
<group targetFramework="net6.0-maccatalyst">
5661
<dependency id="Uno.WinUI" version="1.29.0-dev.93" />
5762

5863
<dependency id="Newtonsoft.Json" version="12.0.2" />
64+
<dependency id="Microsoft.IO.RecyclableMemoryStream" version="2.1.3" />
5965
</group>
6066

6167
<!-- net6.0-macos -->
6268
<group targetFramework="net6.0-macos">
6369
<dependency id="Uno.WinUI" version="1.29.0-dev.93" />
6470

6571
<dependency id="Newtonsoft.Json" version="12.0.2" />
72+
<dependency id="Microsoft.IO.RecyclableMemoryStream" version="2.1.3" />
6673
</group>
6774

6875
<!-- net6.0-android -->
6976
<group targetFramework="net6.0-android">
7077
<dependency id="Uno.WinUI" version="1.29.0-dev.93" />
7178

7279
<dependency id="Newtonsoft.Json" version="12.0.2" />
80+
<dependency id="Microsoft.IO.RecyclableMemoryStream" version="2.1.3" />
81+
</group>
82+
83+
<!-- .NET Standard 2.0 -->
84+
<group targetFramework="netstandard2.0">
85+
<dependency id="Uno.WinUI" version="1.29.0-dev.93" />
86+
87+
<dependency id="Newtonsoft.Json" version="12.0.2" />
88+
<dependency id="Uno.Wasm.WebSockets" version="1.1.0" />
89+
<dependency id="Microsoft.IO.RecyclableMemoryStream" version="2.1.3" />
7390
</group>
91+
</dependencies>
7492

93+
<references>
7594
<!-- .NET Standard 2.0 -->
76-
<group targetFramework="netstandard2.0">
77-
<dependency id="Uno.WinUI" version="1.29.0-dev.93" />
78-
79-
<dependency id="Newtonsoft.Json" version="12.0.2" />
80-
<dependency id="Uno.Wasm.WebSockets" version="1.1.0" />
81-
</group>
82-
</dependencies>
83-
84-
<references>
85-
<!-- .NET Standard 2.0 -->
86-
<group targetFramework="netstandard2.0">
87-
<reference file="Uno.UI.RemoteControl.dll" />
88-
</group>
89-
90-
<!-- iOS -->
91-
<group targetFramework="xamarinios10">
92-
<reference file="Uno.UI.RemoteControl.dll" />
93-
</group>
94-
95-
<!-- macOS -->
96-
<group targetFramework="xamarinmac20">
97-
<reference file="Uno.UI.RemoteControl.dll" />
98-
</group>
95+
<group targetFramework="netstandard2.0">
96+
<reference file="Uno.UI.RemoteControl.dll" />
97+
</group>
98+
99+
<!-- iOS -->
100+
<group targetFramework="xamarinios10">
101+
<reference file="Uno.UI.RemoteControl.dll" />
102+
</group>
103+
104+
<!-- macOS -->
105+
<group targetFramework="xamarinmac20">
106+
<reference file="Uno.UI.RemoteControl.dll" />
107+
</group>
99108

100109
<!-- Android 9.0 -->
101110
<group targetFramework="MonoAndroid11.0">
@@ -119,11 +128,11 @@
119128

120129
</references>
121130
</metadata>
122-
131+
123132
<files>
124-
<!-- Remote Control -->
125-
<file src="..\src\Uno.UI.RemoteControl\bin\Release\netstandard2.0\Uno.UI.RemoteControl.dll" target="lib\netstandard2.0" />
126-
<file src="..\src\Uno.UI.RemoteControl\bin\Release\netstandard2.0\Uno.UI.RemoteControl.pdb" target="lib\netstandard2.0" />
133+
<!-- Remote Control -->
134+
<file src="..\src\Uno.UI.RemoteControl\bin\Release\netstandard2.0\Uno.UI.RemoteControl.dll" target="lib\netstandard2.0" />
135+
<file src="..\src\Uno.UI.RemoteControl\bin\Release\netstandard2.0\Uno.UI.RemoteControl.pdb" target="lib\netstandard2.0" />
127136

128137
<file src="..\src\Uno.UI.RemoteControl\bin\Release\MonoAndroid11.0\Uno.UI.RemoteControl.dll" target="lib\MonoAndroid11.0" />
129138
<file src="..\src\Uno.UI.RemoteControl\bin\Release\MonoAndroid11.0\Uno.UI.RemoteControl.pdb" target="lib\MonoAndroid11.0" />
@@ -163,14 +172,14 @@
163172
<file src="..\src\Uno.UI.RemoteControl\Bin\Uno.UI.RemoteControl.Skia\Release\netstandard2.0\Uno.UI.RemoteControl.*" target="uno-runtime\skia" />
164173

165174
<!-- Remote Control host and integration -->
166-
<file src="..\src\Uno.UI.RemoteControl.Host\bin\Release\netcoreapp3.1\*.*" target="tools\rc\host" />
175+
<file src="..\src\Uno.UI.RemoteControl.Host\bin\Release\netcoreapp3.1\*.*" target="tools\rc\host" />
167176
<file src="..\src\Uno.UI.RemoteControl.VS\bin\Release\net461\*.dll" target="tools\rc\16.0" />
168177
<file src="..\src\Uno.UI.RemoteControl.VS\bin\Release\net461\Newtonsoft.Json.dll" target="tools\rc\16.0" />
169178
<file src="..\src\Uno.UI.RemoteControl.VS\bin\Release\net461\*.pdb" target="tools\rc\16.0" />
170179
<file src="..\src\Uno.UI.RemoteControl.VS\bin\Release\net48\*.dll" target="tools\rc\17.0" />
171180
<file src="..\src\Uno.UI.RemoteControl.VS\bin\Release\net48\*.pdb" target="tools\rc\17.0" />
172181
<file src="..\src\Uno.UI.RemoteControl.VS\bin\Release\net48\Newtonsoft.Json.dll" target="tools\rc\17.0" />
173-
182+
174183
<!-- Force UAP/netx-win to ignore netstandard 2.0 -->
175184
<file src="_._" target="build\uap10.0.16299" />
176185
<file src="_._" target="build\uap10.0.17763" />

src/Uno.UI.RemoteControl.Host/Uno.UI.RemoteControl.Host.csproj

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

3-
<PropertyGroup>
4-
<OutputType>Exe</OutputType>
5-
<TargetFramework>netcoreapp3.1</TargetFramework>
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>netcoreapp3.1</TargetFramework>
66
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
77
</PropertyGroup>
88

@@ -13,14 +13,15 @@
1313
<PackageReference Include="System.Reactive" Version="5.0.0" />
1414
<PackageReference Include="Unity" Version="5.11.10" />
1515
<PackageReference Include="Uno.Core" />
16+
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream" Version="2.1.3" />
1617
</ItemGroup>
1718

1819
<ItemGroup>
1920
<Compile Include="..\Uno.UI.RemoteControl\Helpers\**\*.cs" Link="Helpers/%(Filename)" />
2021
</ItemGroup>
2122

2223
<ItemGroup>
23-
<ProjectReference Include="..\Uno.UI.RemoteControl.Server\Uno.UI.RemoteControl.Server.csproj" />
24+
<ProjectReference Include="..\Uno.UI.RemoteControl.Server\Uno.UI.RemoteControl.Server.csproj" />
2425
</ItemGroup>
2526

2627
<ItemGroup Condition="'$(DocsGeneration)'==''">
@@ -34,7 +35,7 @@
3435
<Target Name="_UnoToolkitOverrideNuget" AfterTargets="AfterBuild" DependsOnTargets="BuiltProjectOutputGroup" Condition="'$(UnoNugetOverrideVersion)'!=''">
3536
<PropertyGroup>
3637
<_baseNugetPath Condition="'$(USERPROFILE)'!=''">$(USERPROFILE)</_baseNugetPath>
37-
<_baseNugetPath Condition="'$(HOME)'!=''">$(HOME)</_baseNugetPath>
38+
<_baseNugetPath Condition="'$(HOME)'!=''">$(HOME)</_baseNugetPath>
3839
<_TargetNugetFolder>$(_baseNugetPath)\.nuget\packages\Uno.UI\$(UnoNugetOverrideVersion)\tools\rc\host</_TargetNugetFolder>
3940
</PropertyGroup>
4041
<ItemGroup>

src/Uno.UI.RemoteControl/Helpers/WebSocketHelper.cs

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,61 @@
11
using System;
2-
using System.Collections.Generic;
3-
using System.IO;
2+
using System.Buffers;
43
using System.Net.WebSockets;
5-
using System.Text;
64
using System.Threading;
75
using System.Threading.Tasks;
6+
using Microsoft.IO;
87
using Uno.UI.RemoteControl.HotReload.Messages;
98

109
namespace Uno.UI.RemoteControl.Helpers
1110
{
1211
public static class WebSocketHelper
1312
{
13+
const int BufferSize = 1 << 16;
14+
private static readonly RecyclableMemoryStreamManager manager = new RecyclableMemoryStreamManager();
15+
1416
public static async Task<Frame> ReadFrame(WebSocket socket, CancellationToken token)
1517
{
16-
byte[] buff = new byte[1 << 16];
17-
var mem = new MemoryStream();
18+
var pool = ArrayPool<byte>.Shared;
19+
var buff = pool.Rent(BufferSize);
20+
var segment = new ArraySegment<byte>(buff);
21+
using var mem = manager.GetStream();
1822

19-
while (true)
23+
try
2024
{
21-
var result = await socket.ReceiveAsync(new ArraySegment<byte>(buff), token);
22-
if (result.MessageType == WebSocketMessageType.Close)
23-
{
24-
return null;
25-
}
26-
27-
if (result.EndOfMessage)
25+
while (true)
2826
{
29-
if (result.Count != 0)
27+
var result = await socket.ReceiveAsync(segment, token);
28+
if (result.MessageType == WebSocketMessageType.Close)
3029
{
31-
mem.Write(buff, 0, result.Count);
30+
return null;
3231
}
3332

34-
mem.Position = 0;
33+
if (result.EndOfMessage)
34+
{
35+
if (result.Count != 0)
36+
{
37+
mem.Write(buff, 0, result.Count);
38+
}
3539

36-
return HotReload.Messages.Frame.Read(mem);
37-
}
38-
else
39-
{
40-
mem.Write(buff, 0, result.Count);
40+
mem.Position = 0;
41+
42+
return Frame.Read(mem);
43+
}
44+
else
45+
{
46+
mem.Write(buff, 0, result.Count);
47+
}
4148
}
4249
}
50+
finally
51+
{
52+
pool.Return(buff);
53+
}
4354
}
4455

4556
internal static async Task SendFrame(WebSocket webSocket, Frame frame, CancellationToken ct)
4657
{
47-
var stream = new MemoryStream();
58+
using var stream = manager.GetStream();
4859
frame.WriteTo(stream);
4960

5061
await webSocket.SendAsync(new ArraySegment<byte>(stream.GetBuffer(), 0, (int)stream.Length), WebSocketMessageType.Binary, true, ct);

src/Uno.UI.RemoteControl/Uno.UI.RemoteControl.Skia.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
<ItemGroup>
5353
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
5454
<PackageReference Include="Uno.MonoAnalyzers" />
55+
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream" Version="2.1.3" />
5556
</ItemGroup>
5657

5758
<ItemGroup>

src/Uno.UI.RemoteControl/Uno.UI.RemoteControl.Wasm.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
<ItemGroup>
4747
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
4848
<PackageReference Include="Uno.MonoAnalyzers" />
49+
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream" Version="2.1.3" />
4950
</ItemGroup>
5051

5152
<ItemGroup>

0 commit comments

Comments
 (0)