- Регистрация
- 08.11.2015
- Сообщения
- 1 795
- Благодарностей
- 2 478
- Баллы
- 113
Пытаюсь решить задачку...
Есть 2 байтовых массива + нужно подобрать третий согласно условий.
Набросал кодец, и всё хорошо, вычисляет где-то 2-5 секунд нужное значение.
Но, меня уж очень беспокоит, можно ли как-то усовершенствовать, чтобы сделать хотя бы в 10 раз быстрее.
Специалисты, помогите ускорить код пожалуйста....
Из того, что сам пытался - переписал код под IEnumerable и yield чтобы вместо for дёргать в AsParallel - это в свою очередь повысило скорость в 2 раза.
Но, мне кажется, что я что-то упускаю...
Пробовал сгенерировать последовательность, например от 0 до 10 000 000 и пытался дёргать через for, AsParallel - в результате скорость возросла с 2-5 секунд до 16-20 секунд (хотя, мне казалось, что если поместить значения уже в ОЗУ, то должно было бы работать быстрее...).
Что можно ещё попробовать?
Накидайте вариантов пожалуйста....
Скриншот того, что уже есть. Можно быстрее? Если можно - как?
P.S.
Избавился от
P.S. Ещё чуток подшаманил..
Оказалось, что переводил в hash16 результат написаной на коленке функцией, и она получается работала медленнее, чем BitConverter. Пришлось вернуть его обратно (в момент вывода результата). 3 000 000 было 4 секунды, сейчас 3 200 000 считает за 2.8 секунды Ещё чего-то не хватает... Продолжаю шаманить...
P.S. Оказалось что в конструкции AsParallel есть опция, с которой данную работу делает быстрее, чем без нее. Хотя... Также думал о том, что мол задача на 1кк элементов должна бы заставить LINQ использовать параллелизм (чтобы ускорить), но он оказывается думает иначе и без опции видимо считает через раз (один раз параллельно, другой - последовательно).
P.S. И вот наконец-то я нашел ту волшебную таблетку, которую искал.
Необходимо создавать:
И потом дёргать его...
И на выходе 3 360 000 хешей за 2.68 (если гадать последовательно):
Или чуть больше времени если заполнять nonce используя рандом:
В итоге, на сколько я понял продолжать копать дальше нет смысла.
Оптимальный вариант использовать Enumerable, AsParallel с включеной опцией параллелизма, использовать yield с целью замены for. Также штуки которые приходится создавать несколько раз - создаем один раз в виде статического поля. И... Да здравствует производительность...
Есть 2 байтовых массива + нужно подобрать третий согласно условий.
Набросал кодец, и всё хорошо, вычисляет где-то 2-5 секунд нужное значение.
Но, меня уж очень беспокоит, можно ли как-то усовершенствовать, чтобы сделать хотя бы в 10 раз быстрее.
Специалисты, помогите ускорить код пожалуйста....
C#:
long outdata = 0;
byte[] data1 = new byte[]{ 0, 0, 144, 134, 3 };
byte[] data2 = new byte[]{ 131, 20, 26, 31, 187, 62, 81, 252, 159, 53, 196};
System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch();
project.SendInfoToLog("Старт");
timer.Start();
for(long i = 0; i<long.MaxValue;i++) {
byte[] data3 = BitConverter.GetBytes(i);
byte[] rv = new byte[data1.Length + data2.Length + data3.Length];
System.Buffer.BlockCopy(data1, 0, rv, 0, data1.Length);
System.Buffer.BlockCopy(data2, 0, rv, data1.Length, data2.Length);
System.Buffer.BlockCopy(data3, 0, rv, data1.Length + data2.Length, data3.Length);
int[] data4 = new int[6];
using(var sha256 = System.Security.Cryptography.SHA256.Create()) {
byte[] m = sha256.ComputeHash(rv);
string data5 = BitConverter.ToString(m).Replace("-", string.Empty).Remove(5);
for(int j=0;j<data5.Length;j++) {
data4[j] = int.Parse(data5[j].ToString(), System.Globalization.NumberStyles.HexNumber);
}
}
int sum = data4.Sum() - data4.Last();
if(sum == 0 && data4.Last() < 2) {
outdata = i;
break;
}
}
timer.Stop();
project.SendInfoToLog(string.Format(@"End. {0:mm}:{0:ss}.{0:fff} {1}",timer.Elapsed, outdata ),true);
Из того, что сам пытался - переписал код под IEnumerable и yield чтобы вместо for дёргать в AsParallel - это в свою очередь повысило скорость в 2 раза.
Но, мне кажется, что я что-то упускаю...
Пробовал сгенерировать последовательность, например от 0 до 10 000 000 и пытался дёргать через for, AsParallel - в результате скорость возросла с 2-5 секунд до 16-20 секунд (хотя, мне казалось, что если поместить значения уже в ОЗУ, то должно было бы работать быстрее...).
Что можно ещё попробовать?
Накидайте вариантов пожалуйста....
Скриншот того, что уже есть. Можно быстрее? Если можно - как?
P.S.
Избавился от
BitConverter.ToString(m).Replace("-", string.Empty).Remove(5);
- ещё чуток подкрутил производительность... Надеялся, что как-то побольше результат будет от этого... В итоге - почти не заметно...
C#:
byte[] m = sha256.ComputeHash(bytes).ToArray();
if(m[0] == m[1] && m[1] == 0 && m[2] < 16) return true;
return false;
P.S. Ещё чуток подшаманил..
Оказалось, что переводил в hash16 результат написаной на коленке функцией, и она получается работала медленнее, чем BitConverter. Пришлось вернуть его обратно (в момент вывода результата). 3 000 000 было 4 секунды, сейчас 3 200 000 считает за 2.8 секунды Ещё чего-то не хватает... Продолжаю шаманить...
BitConverter.ToString(bytes).Replace("-", string.Empty).ToLower();
P.S. Оказалось что в конструкции AsParallel есть опция, с которой данную работу делает быстрее, чем без нее. Хотя... Также думал о том, что мол задача на 1кк элементов должна бы заставить LINQ использовать параллелизм (чтобы ускорить), но он оказывается думает иначе и без опции видимо считает через раз (один раз параллельно, другой - последовательно).
C#:
// Код без опции WithExecutionMode - медленнее
//return m.AsParallel().WithDegreeOfParallelism(count_processor)
// .Where(x => x.CheckHash(nonce)).First().ToHex16();
// Остановился на этом...
return m.AsParallel().WithExecutionMode(ParallelExecutionMode.ForceParallelism).WithDegreeOfParallelism(count_processor)
.Where(x => x.CheckHash(nonce)).First().ToHex16();
Необходимо создавать:
C#:
private static readonly SHA256 sha256f = SHA256.Create();
C#:
byte[] m = sha256f.ComputeHash(bytes);
if(m[0] == m[1] && m[1] == 0 && m[2] < 16)
return true;
return false;
Или чуть больше времени если заполнять nonce используя рандом:
В итоге, на сколько я понял продолжать копать дальше нет смысла.
Оптимальный вариант использовать Enumerable, AsParallel с включеной опцией параллелизма, использовать yield с целью замены for. Также штуки которые приходится создавать несколько раз - создаем один раз в виде статического поля. И... Да здравствует производительность...
Последнее редактирование: