Я пытался реализовать алгоритм, указанный в этой статье: [здесь - пожалуйста, игнорируйте математику, поскольку она не имеет отношения к вопросу] [2]. Этот алгоритм очень прост в формальном концептуальном анализе. Вход представляет собой матрицу NXM
, хранящуюся как X
и .
в TXT-файле. В соответствии с введенным в документе псевдокодом вход должен быть представлен как матрицаРеализация алгоритма в C# представляется катастрофической
ответ
Не имея возможности увидеть источник реализации C++, с которым вы сравниваете, невозможно точно сказать, почему это намного быстрее, чем ваш код на C#, но поскольку каждое из ваших значений равно 0 или 1, то одна оптимизация, которую вы можете сделать (за счет повышения вашего кода), заключается в том, чтобы хранить значения в какой-либо структуре данных битмаски или точно так же, как упакованные значения битов в массивах int и использовать операции манипуляции бит, чтобы манипулировать ими. Возможно, реализация C++ делает это, но это не показано в опубликованном псевдокоде для удобства объяснения.
Например, поскольку CT_WIDTH равно 126, вы можете сохранить одну строку в 4 х 32-разрядных целых числах (128 бит) вместо 126 целых чисел.
Тогда такие операции, как это:
match = true;
for (int j = 0; j < CT_WIDTH; j++)
{
if (B[j] == 1 && FCAContext[rows[y][i] * CT_WIDTH + j] == 0)
{
match = false;
break;
}
}
Может быть переписано, как это, эффективно обрабатывать 32 значений одновременно:
// CT_WIDTH_SHIFTED = (CT_WIDTH + 31)/32
match = true;
int index = rows[y][i] * CT_WIDTH_SHIFTED;
for (int j = 0; j < CT_WIDTH_SHIFTED; j++)
{
if (B[j] & FCAContext[index + j] != B[j])
{
match = false;
break;
}
}
Аналогично, это:
for (int j = 0; j < CT_WIDTH; j++)
if (FCAContext[rows[y][i] * CT_WIDTH + j] == 0)
D[j] = 0;
Может быть переписана как
for (int j = 0; j < CT_WIDTH_SHIFTED; j++)
D[j] &= FCAContext[index + j];
Значения в FCAContext, D и B должны храниться как упакованные биты.
Например, чтобы установить бит в массиве, вместо того, чтобы использовать такой код, чтобы установить ий элемент в целочисленном массиве:
B[j] = 1;
вы бы прежде всего вычислить индекс путем деления J на 32, сдвинув влево на 5 (j >> 5) и вычислив бит внутри элемента следующим образом: < < (j & 31), который сдвинут справа на оставшуюся часть j, деленную на 32, затем установите его побитно ИЛИ:
B[j >> 5] |= 1 << (j & 31)
Here's онлайн-учебник о маскировании бит. Дополнительные сведения см. В разделе «Бит-манипуляция», «бит-сдвиг», «бит-маскировка», «бит-хакинг» и «бит-операции»/«побитовые операции». Бит-манипуляция может быть довольно затруднительной и делает ваш код трудным для чтения.
Также рассмотрите возможность использования класса .NET BitArray.
вы можете уточнить свой вопрос, чтобы больше узнать о битовой маске? –
Я просто не хочу rstand this // // CT_WIDTH_SHIFTED = (CT_WIDTH + 31) >> 5' –
Он вычисляет количество 32-битных целых чисел, необходимых для хранения 126 бит. Добавление 31 состоит в том, чтобы убедиться, что значение округлено, потому что это означает, что результат будет одним большим, за исключением тех случаев, когда CT_WIDTH точно делится на 32. (126 + 31)/32 = 4 (целочисленное деление) – samgak
- 1. Реализация алгоритма планирования C++
- 2. Реализация алгоритма синхронизации в C#
- 3. Реализация алгоритма оболочки в C
- 4. Реализация алгоритма SURF в C#
- 5. Реализация алгоритма LEM2 в C#
- 6. Реализация алгоритма Алгоритма восстановления
- 7. Реализация алгоритма в Javascript
- 8. Реализация алгоритма алгоритма быстрой реализации
- 9. Реализация алгоритма?
- 10. C/C++ реализация алгоритма, аналогичного подмножеству sum
- 11. реализация алгоритма Cormen HeapSort в C
- 12. Реализация алгоритма Флойда Стейнберга в C#
- 13. HMAC - реализация алгоритма PHP в Objective-C
- 14. Реализация алгоритма Prim в ошибке C++ STL?
- 15. Реализация базового алгоритма MD5 в C++
- 16. Реализация алгоритма отслеживания вакансий в C++
- 17. Реализация алгоритма в Python
- 18. Реализация алгоритма в bash
- 19. Реализация алгоритма максимального прямоугольника
- 20. Реализация алгоритма для улучшения
- 21. Понимание ulps в катастрофической отмены
- 22. Реализация квадратичного алгоритма
- 23. Реализация жесткого алгоритма
- 24. Реализация алгоритма Strassen's
- 25. Реализация алгоритма кучи MinMax
- 26. Реализация алгоритма P_SHA1 в PHP
- 27. Реализация алгоритма маршевого куба?
- 28. Реализация алгоритма согласования алгоритмов
- 29. Реализация алгоритма SVD
- 30. Реализация алгоритма LZ78 в Java
Предполагая, что ваши фактические тестовые измерения игнорируют время JIT, и вы запускаете сборку релизов без отладчика ... Следующим шагом будет пользовательский профилировщик и посмотреть, куда больше всего потрачено ... Как правило, такой вопрос будет интересен, и вы получите оптимизированную версию без любые усилия на вашей стороне (также это скорее всего игра). –
Не похоже, что я просто хочу его оптимизировать, мне нужно понять, насколько C# так же хорош, как C++, или я должен покинуть мир .net и перейти на другой язык, который разработан вокруг реализации алгоритмов. –
Без [хорошего, _minimal_, _complete_ кода пример] (https: // StackOverflow.com/help/mcve), который надежно демонстрирует проблему, вы вряд ли получите какой-либо конкретный ответ, который поможет. Что касается того, что _ «C# так же хорош, как C++» _, это, безусловно, есть, но каждый язык имеет свои сильные и слабые стороны. Тем не менее, даже наивно-но функционально реализованная версия C++-алгоритма должна составлять 10-20% от производительности неуправляемого кода, и с усилием (и, возможно, с использованием «небезопасного» кода) должна быть достигнута четность. Разница в 35 раз несложна для правильно выполненного порта. –