Skip to content

Commit 208c0c7

Browse files
committed
Remove memcmp from MessagePackString. Fix #206.
P/Invoke causes verification error in Windows Native. It gains performance for edge case -- comparing (relatively) large blob (not string). It is clearly rare, and it may bring packaging issue in future. In addition, it is not so bad naive managed loop. In best (or worst) case, it only 1.8x slower than memcmp. Although it is 12x slower when it is well aligned bytes, but it should be rare in real world. So, memcmp has gone.
1 parent 1a54b40 commit 208c0c7

9 files changed

Lines changed: 18 additions & 413 deletions

File tree

CHANGES.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,9 @@ Release 0.9.0 beta1 2016/09/24
616616

617617
Release 0.9.0 (planned)
618618

619+
BREAKING CHANGES
620+
* MessagePackObject comparison which have large binary data will be about 2x - 18x slower in .NET 3.5/4.5/4.6(other platforms will not be affected).
621+
619622
NEW FEATURES
620623
* Users of serializer code generator API can specify TextWriter to output. This may improve tooling chain.
621624
* Users of serializer code generator API can suppress [DebuggerNonUserCode] attribute to enable debugger step in.
@@ -629,4 +632,5 @@ Release 0.9.0 (planned)
629632
* Fix extra field causes IndexOutOfBoundException when reflection based serializers are used. Issue #199
630633
* Fix some built-in serializers throws InvalidOperationException instead of SerializationException for type errors. Issue #204
631634
* Fix a combination of readonly members and collection members incorrect code generation when the type also have deserialization constructor. Issue #207.
635+
* Fix Windows Native build error. Issue #206.
632636

MsgPack.sln

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,6 @@ EndProject
4343
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MsgPack.Net45", "src\MsgPack.Net45\MsgPack.Net45.csproj", "{9C7B55A6-AF7F-4D26-AB5B-297B7FF25B6D}"
4444
EndProject
4545
Global
46-
GlobalSection(Performance) = preSolution
47-
HasPerformanceSessions = true
48-
EndGlobalSection
4946
GlobalSection(SolutionConfigurationPlatforms) = preSolution
5047
CodeAnalysis|Any CPU = CodeAnalysis|Any CPU
5148
CodeAnalysis|ARM = CodeAnalysis|ARM

src/MsgPack.Net35/MsgPack.Net35.csproj

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1020,9 +1020,6 @@
10201020
<Compile Include="..\MsgPack\UnpackingStreamReader.cs">
10211021
<Link>UnpackingStreamReader.cs</Link>
10221022
</Compile>
1023-
<Compile Include="..\MsgPack\UnsafeNativeMethods.cs">
1024-
<Link>UnsafeNativeMethods.cs</Link>
1025-
</Compile>
10261023
<Compile Include="..\MsgPack\Validation.cs">
10271024
<Link>Validation.cs</Link>
10281025
</Compile>

src/MsgPack.Net45/MsgPack.Net45.csproj

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1057,9 +1057,6 @@
10571057
<Compile Include="..\MsgPack\UnpackingStreamReader.cs">
10581058
<Link>UnpackingStreamReader.cs</Link>
10591059
</Compile>
1060-
<Compile Include="..\MsgPack\UnsafeNativeMethods.cs">
1061-
<Link>UnsafeNativeMethods.cs</Link>
1062-
</Compile>
10631060
<Compile Include="..\MsgPack\Validation.cs">
10641061
<Link>Validation.cs</Link>
10651062
</Compile>

src/MsgPack.Silverlight.5/MsgPack.Silverlight.5.csproj

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@
5656
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'CodeAnalysis|AnyCPU'">
5757
<OutputPath>bin\CodeAnalysis\</OutputPath>
5858
<DefineConstants>TRACE;SILVERLIGHT;CODE_ANALYSIS</DefineConstants>
59-
<DocumentationFile></DocumentationFile>
59+
<DocumentationFile>
60+
</DocumentationFile>
6061
<Optimize>true</Optimize>
6162
<NoStdLib>true</NoStdLib>
6263
<DebugType>pdbonly</DebugType>
@@ -776,9 +777,6 @@
776777
<Compile Include="..\MsgPack\UnpackingStreamReader.cs">
777778
<Link>UnpackingStreamReader.cs</Link>
778779
</Compile>
779-
<Compile Include="..\MsgPack\UnsafeNativeMethods.cs">
780-
<Link>UnsafeNativeMethods.cs</Link>
781-
</Compile>
782780
<Compile Include="Properties\AssemblyInfo.cs" />
783781
<Compile Include="Serialization\LockRecursionPolicy.cs" />
784782
<Compile Include="Serialization\ReaderWriterLockSlim.cs" />

src/MsgPack/MessagePackString.cs

Lines changed: 10 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -266,30 +266,21 @@ private static bool EqualsEncoded( MessagePackString left, MessagePackString rig
266266
return false;
267267
}
268268

269-
#if !UNITY && !WINDOWS_PHONE && !NETFX_CORE
270-
if ( _isFastEqualsDisabled == 0 )
271-
{
272-
try
273-
{
274-
return UnsafeFastEquals( left._encoded, right._encoded );
275-
}
276-
catch ( SecurityException )
277-
{
278-
Interlocked.Exchange( ref _isFastEqualsDisabled, 1 );
279-
}
280-
catch ( MemberAccessException )
281-
{
282-
Interlocked.Exchange( ref _isFastEqualsDisabled, 1 );
283-
}
284-
}
285-
#endif // if !UNITY && !WINDOWS_PHONE && !NETFX_CORE
286-
287269
return SlowEquals( left._encoded, right._encoded );
288270
}
289271

272+
// It is 1.8x(not-aligned) - 11.1x (well-aligned) slower than memcmp, but this call is rare and it is acceptable in most cases.
273+
// It is roughly equal to String.Equals(String).
290274
private static bool SlowEquals( byte[] x, byte[] y )
291275
{
292-
for ( int i = 0; i < x.Length; i++ )
276+
if ( x.Length != y.Length )
277+
{
278+
return false;
279+
}
280+
281+
// This looks naive, but loop expansion or unsafe code is not effect here (unsafe is more slower).
282+
283+
for ( var i = 0; i < x.Length; i++ )
293284
{
294285
if ( x[ i ] != y[ i ] )
295286
{
@@ -300,44 +291,6 @@ private static bool SlowEquals( byte[] x, byte[] y )
300291
return true;
301292
}
302293

303-
#if !UNITY && !WINDOWS_PHONE && !NETFX_CORE
304-
#if SILVERLIGHT
305-
private static int _isFastEqualsDisabled =
306-
System.Windows.Application.Current.HasElevatedPermissions ? 0 : 1;
307-
#else
308-
private static int _isFastEqualsDisabled;
309-
#endif // if SILVERLIGHT
310-
311-
#if DEBUG
312-
// for testing
313-
internal static bool IsFastEqualsDisabled
314-
{
315-
get { return _isFastEqualsDisabled != 0; }
316-
}
317-
#endif
318-
319-
#if !NETFX_35 && !UNITY
320-
[SecuritySafeCritical]
321-
#endif // !NETFX_35 && !UNITY
322-
private static bool UnsafeFastEquals( byte[] x, byte[] y )
323-
{
324-
#if DEBUG
325-
Contract.Assert( x != null, "x != null" );
326-
Contract.Assert( y != null, "y != null" );
327-
Contract.Assert( 0 < x.Length, "0 < x.Length" );
328-
Contract.Assert( x.Length == y.Length, "x.Length == y.Length" );
329-
#endif // if DEBUG
330-
int result;
331-
if ( !UnsafeNativeMethods.TryMemCmp( x, y, new UIntPtr( unchecked( ( uint )x.Length ) ), out result ) )
332-
{
333-
Interlocked.Exchange( ref _isFastEqualsDisabled, 1 );
334-
return SlowEquals( x, y );
335-
}
336-
337-
return result == 0;
338-
}
339-
#endif // if !UNITY && !WINDOWS_PHONE && !NETFX_CORE
340-
341294
#if !SILVERLIGHT && !NETSTANDARD1_1 && !NETSTANDARD1_3
342295
[Serializable]
343296
#endif // !SILVERLIGHT && !NETSTANDARD1_1 && !NETSTANDARD1_3

src/MsgPack/MsgPack.csproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -541,7 +541,6 @@
541541
<Compile Include="UnpackingMode.cs" />
542542
<Compile Include="UnpackingStream.cs" />
543543
<Compile Include="UnpackingStreamReader.cs" />
544-
<Compile Include="UnsafeNativeMethods.cs" />
545544
<Compile Include="Validation.cs" />
546545
<Compile Include="UnpackingResult.cs" />
547546
<Compile Include="Unpacker.cs" />

src/MsgPack/UnsafeNativeMethods.cs

Lines changed: 0 additions & 103 deletions
This file was deleted.

0 commit comments

Comments
 (0)