From a5cd123fd57e38c790fe5bb06e45990cff74505b Mon Sep 17 00:00:00 2001 From: lights li Date: Sun, 17 Mar 2019 02:48:23 +0800 Subject: [PATCH] speed up Uint160.CompareTo and Uint256.CompareTo function (#552) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix zero connect * speed up bytes.CompareTo X3 times maybe more. * Update UInt256.cs * fix a length error * make uint benchmarks short,becauce can't pass github test. * cleanup --- neo.UnitTests/UT_UIntBenchmarks.cs | 45 +++++++++++++----------------- neo/UInt160.cs | 35 ++++++++++++++++------- neo/UInt256.cs | 35 ++++++++++++++++------- 3 files changed, 69 insertions(+), 46 deletions(-) diff --git a/neo.UnitTests/UT_UIntBenchmarks.cs b/neo.UnitTests/UT_UIntBenchmarks.cs index 1c388354a5..be43120d6f 100644 --- a/neo.UnitTests/UT_UIntBenchmarks.cs +++ b/neo.UnitTests/UT_UIntBenchmarks.cs @@ -1,21 +1,14 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; -using Neo.Cryptography.ECC; -using Neo.IO; -using Neo.Ledger; -using System.Collections.Generic; -using System.IO; -using System.Text; -using System.Diagnostics; using System; -//using System.Runtime.CompilerServices.Unsafe; +using System.Diagnostics; namespace Neo.UnitTests { [TestClass] public class UT_UIntBenchmarks { - int MAX_TESTS = 1000000; // 1 million + private const int MAX_TESTS = 1000; byte[][] base_32_1; byte[][] base_32_2; @@ -35,7 +28,7 @@ public void TestSetup() base_20_1 = new byte[MAX_TESTS][]; base_20_2 = new byte[MAX_TESTS][]; - for(var i=0; i { var checksum = 0; - for(var i=0; i { var checksum = 0; - for(var i=0; i { var checksum = 0; - for(var i=0; i { var checksum = 0; - for(var i=0; i { var checksum = 0; - for(var i=0; i { var checksum = 0; - for(var i=0; i { var checksum = 0; - for(var i=0; i { var checksum = 0; - for(var i=0; i= 0; i--) + for (int i = 256 / 32 - 1; i >= 0; i--) { if (lpx[i] > lpy[i]) return 1; @@ -257,7 +250,7 @@ private unsafe int code3_UInt256CompareTo(byte[] b1, byte[] b2) { ulong* lpx = (ulong*)px; ulong* lpy = (ulong*)py; - for (int i = 256/64-1; i >= 0; i--) + for (int i = 256 / 64 - 1; i >= 0; i--) { if (lpx[i] > lpy[i]) return 1; @@ -287,7 +280,7 @@ private unsafe int code2_UInt160CompareTo(byte[] b1, byte[] b2) { uint* lpx = (uint*)px; uint* lpy = (uint*)py; - for (int i = 160/32-1; i >= 0; i--) + for (int i = 160 / 32 - 1; i >= 0; i--) { if (lpx[i] > lpy[i]) return 1; diff --git a/neo/UInt160.cs b/neo/UInt160.cs index 5629dfa7db..ad70573eb0 100644 --- a/neo/UInt160.cs +++ b/neo/UInt160.cs @@ -31,16 +31,20 @@ public UInt160(byte[] value) /// Method CompareTo returns 1 if this UInt160 is bigger than other UInt160; -1 if it's smaller; 0 if it's equals /// Example: assume this is 01ff00ff00ff00ff00ff00ff00ff00ff00ff00a4, this.CompareTo(02ff00ff00ff00ff00ff00ff00ff00ff00ff00a3) returns 1 /// - public int CompareTo(UInt160 other) + public unsafe int CompareTo(UInt160 other) { - byte[] x = ToArray(); - byte[] y = other.ToArray(); - for (int i = x.Length - 1; i >= 0; i--) + fixed (byte* px = ToArray(), py = other.ToArray()) { - if (x[i] > y[i]) - return 1; - if (x[i] < y[i]) - return -1; + uint* lpx = (uint*)px; + uint* lpy = (uint*)py; + //160 bit / 32 bit step -1 + for (int i = (160 / 32 - 1); i >= 0; i--) + { + if (lpx[i] > lpy[i]) + return 1; + if (lpx[i] < lpy[i]) + return -1; + } } return 0; } @@ -48,9 +52,20 @@ public int CompareTo(UInt160 other) /// /// Method Equals returns true if objects are equal, false otherwise /// - bool IEquatable.Equals(UInt160 other) + public unsafe bool Equals(UInt160 other) { - return Equals(other); + fixed (byte* px = ToArray(), py = other.ToArray()) + { + uint* lpx = (uint*)px; + uint* lpy = (uint*)py; + //160 bit / 32 bit(uint step) -1 + for (int i = (160 / 32 - 1); i >= 0; i--) + { + if (lpx[i] != lpy[i]) + return false; + } + } + return true; } /// diff --git a/neo/UInt256.cs b/neo/UInt256.cs index c32a5df5a5..37045b9b94 100644 --- a/neo/UInt256.cs +++ b/neo/UInt256.cs @@ -32,16 +32,20 @@ public UInt256(byte[] value) /// Method CompareTo returns 1 if this UInt256 is bigger than other UInt256; -1 if it's smaller; 0 if it's equals /// Example: assume this is 01ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00a4, this.CompareTo(02ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00a3) returns 1 /// - public int CompareTo(UInt256 other) + public unsafe int CompareTo(UInt256 other) { - byte[] x = ToArray(); - byte[] y = other.ToArray(); - for (int i = x.Length - 1; i >= 0; i--) + fixed (byte* px = ToArray(), py = other.ToArray()) { - if (x[i] > y[i]) - return 1; - if (x[i] < y[i]) - return -1; + ulong* lpx = (ulong*)px; + ulong* lpy = (ulong*)py; + //256bit / 64bit(ulong step) -1 + for (int i = (256 / 64 - 1); i >= 0; i--) + { + if (lpx[i] > lpy[i]) + return 1; + if (lpx[i] < lpy[i]) + return -1; + } } return 0; } @@ -49,9 +53,20 @@ public int CompareTo(UInt256 other) /// /// Method Equals returns true if objects are equal, false otherwise /// - bool IEquatable.Equals(UInt256 other) + public unsafe bool Equals(UInt256 other) { - return Equals(other); + fixed (byte* px = ToArray(), py = other.ToArray()) + { + ulong* lpx = (ulong*)px; + ulong* lpy = (ulong*)py; + //256bit / 64bit(ulong step) -1 + for (int i = (256 / 64 - 1); i >= 0; i--) + { + if (lpx[i] != lpy[i]) + return false; + } + } + return true; } ///