110,534
社区成员
发帖
与我相关
我的任务
分享
Debug.WriteLine("并行 Test start");
Parallel.ForEach(list, new ParallelOptions() { MaxDegreeOfParallelism = 6 }, async (i) =>
{
Debug.WriteLine($"并行 {i} 开始 {DateTime.Now.ToString("mm:ss:ffff")}");
var tmp = await TestAsync1(1);
});
Debug.WriteLine($"并行总时间{DateTime.Now - d}");
public static string Sign(byte[] message, ECDsaSigner _ECDsaSigner, byte[] uncompressedPublicKey/*, ECKey _ecKey*/)
{
DateTime d = DateTime.Now;
DateTime d2 = DateTime.Now;
var byteList = new List<byte>();
var bytePrefix = "0x19".HexToByteArray();
var textBytePrefix = Encoding.UTF8.GetBytes("Ethereum Signed Message:\n" + message.Length);
byteList.AddRange(bytePrefix);
byteList.AddRange(textBytePrefix);
byteList.AddRange(message);
var plainMessage = byteList.ToArray();
Console.WriteLine($"步骤:1 {(DateTime.Now - d)}");
d = DateTime.Now;
KeccakDigest digest = new KeccakDigest(256);
byte[] hash = new byte[digest.GetDigestSize()];
digest.BlockUpdate(plainMessage, 0, plainMessage.Length);
digest.DoFinal(hash, 0);
Console.WriteLine($"步骤:2 {(DateTime.Now - d)}");
d = DateTime.Now;
var tmp = _ECDsaSigner.GenerateSignature(hash);
Console.WriteLine($"步骤:3 {(DateTime.Now - d)}");
d = DateTime.Now;
var tmp2 = new ECDSASignature(tmp);
Console.WriteLine($"步骤:4 {(DateTime.Now - d)}");
d = DateTime.Now;
var byte_tmp = tmp2.ToDER();
Console.WriteLine($"步骤:5 {(DateTime.Now - d)}");
d = DateTime.Now;
var sig = ECDSASignature.FromDER(byte_tmp);
Console.WriteLine($"步骤:6 {(DateTime.Now - d)}");
d = DateTime.Now;
var ECDSAsignature = sig.MakeCanonical();
Console.WriteLine($"步骤:7 {(DateTime.Now - d)}");
d = DateTime.Now;
var recId = -1;
for (var i = 0; i < 4; i++)
{
ECKey rec = ECKey.RecoverFromSignature(i, ECDSAsignature, hash, false);
if (rec != null)
{
var k = rec.GetPubKey(false);
Console.WriteLine($"步骤:8-{i} {(DateTime.Now - d)}");
if (k != null && k.SequenceEqual(uncompressedPublicKey))
{
recId = i;
break;
}
}
}
if (recId == -1)
throw new Exception("Could not construct a recoverable key. This should never happen.");
Console.WriteLine($"步骤:8 {(DateTime.Now - d)}");
d = DateTime.Now;
ECDSAsignature.V = new[] { (byte)(recId + 27) };
var t2 = "0x" + ECDSAsignature.R.ToByteArrayUnsigned().ToHex().PadLeft(64, '0') +
ECDSAsignature.S.ToByteArrayUnsigned().ToHex().PadLeft(64, '0') +
ECDSAsignature.V.ToHex();
Console.WriteLine($"步骤:9 {(DateTime.Now - d)}");
Debug.WriteLine($"{DateTime.Now.ToString("mm:ss:ffff")} 签名总耗时 {(DateTime.Now - d2)}");
return t2;
}
代码中有一些检查签名耗时的一些婴儿代码。别见怪。。~~为了速度还吧一些对象提前实例化,静态化。随意参数有所改动。但是实际这些耗时都不高。
最耗时的是var tmp = _ECDsaSigner.GenerateSignature(hash); 和
ECKey rec = ECKey.RecoverFromSignature(i, ECDSAsignature, hash, false);
这两条语句。是个椭圆DSA算法。。也已经独立抽离出来。但是没能力简化和提高运算速度。。
Parallel.ForEach(list, new ParallelOptions() { MaxDegreeOfParallelism = 6 }, (i) =>
{
string tmp = 纯cpu运算操作签名异步函数,是一个椭圆ECDSA算法(1).Result;
});
await Task.WhenAll(getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x),
getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x),
getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x),
getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x),
getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x),
getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x),
getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x),
getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x),
getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x),
getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x),
getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x),
getMD5(x), getMD5(x)
我加这么多跑,结果75ms,可见他当然是并行的 static async Task Main(string[] args)
{
string x = string.Join("", Enumerable.Repeat(1, 100));
Stopwatch watch = new Stopwatch();
watch.Start();
await Task.WhenAll(getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x), getMD5(x),
getMD5(x), getMD5(x)
);
watch.Stop();
Console.WriteLine(watch.Elapsed.TotalMilliseconds);
Console.ReadKey();
}
static MD5 md5 = MD5.Create();
public static async Task<string> getMD5(string str)
{
using (Stream ms = await CreateStrem(str).ConfigureAwait(false))
{
var x = await Task<byte[]>.Run(() =>
{
return md5.ComputeHash(ms);
}).ConfigureAwait(false);
return UTF8Encoding.UTF8.GetString(x);
}
}
public static Task<Stream> CreateStrem(string x)
{
return Task<Stream>.Run(async () =>
{
MemoryStream ms = new MemoryStream();
await ms.WriteAsync(UTF8Encoding.UTF8.GetBytes(x));
ms.Seek(0, SeekOrigin.Begin);
return (Stream) ms;
});
}
除了统计输出,我没有加入其他任何输出,因为控制台输出会干扰统计。
实际结果:单独运算一个和并发10个没有任何区别,我测试机跑一个22ms,跑10个还是22ms。其实22ms对于计算机来说是无压力的,进的快,走的也快(小学题:一个进水,一个出水。22ms对计算机来说近乎是进水等于出水的节奏,)
ps:22ms是在控制台直接运行,不是在vs里跑的,vs跑的快要*10,因为vs启动诊断等等附加开销