Производительность Типа данных decimal C#

http://msdn.microsoft.com/en-us/library/system.string.split.aspx

Пример из документов:

string source = "[stop]ONE[stop][stop]TWO[stop][stop][stop]THREE[stop][stop]";
string[] stringSeparators = new string[] {"[stop]"};
string[] result;

// ...
result = source.Split(stringSeparators, StringSplitOptions.None);

foreach (string s in result)
{
    Console.Write("'{0}' ", String.IsNullOrEmpty(s) ? "<>" : s);
}

54
задан tempw 15 December 2008 в 09:21
поделиться

7 ответов

Спустя 4 года после моего предыдущий ответ я хотел бы добавить другой на основе опыта, который мы имели за эти годы при работе с высокоэффективными вычислениями с числами с плавающей запятой.

существует две основных проблемы с Decimal тип данных на высокоэффективных вычислениях:

  1. CLR рассматривает этот тип как регулярную структуру (никакая специальная поддержка что касается других встроенных типов)
  2. В 128 битов

, В то время как Вы не можете сделать многого о первом выпуске, вторые еще более важные взгляды. Операции памяти и процессоры чрезвычайно эффективны при работе с 64-разрядными числами. 128-разрядные операции намного более тяжелы. Таким образом реализация.NET Decimal дизайном значительно медленнее что операция на Double даже для операций чтения-записи.

, Если для Вашего приложения нужны и точность вычислений с плавающей точкой и в выполнение таких операций затем никакой Double или Decimal, подходят для задачи. Решение, которое мы приняли в моей компании (домен Fintech) состоит в том, чтобы использовать обертку сверху IntelВ® Decimal Математическая Библиотека С плавающей точкой . Это реализует IEEE 754-2008 Decimal Floating-Point Arithmetic specification обеспечивающие 64-разрядные десятичные числа с плавающей точкой.

Комментарии. Decimals должен только использоваться для хранения чисел с плавающей запятой и простых арифметических операций на них. Вся тяжелая математика как вычисление индикаторов для технического анализа должна быть выполнена на Double значения.

0
ответ дан 7 November 2019 в 08:02
поделиться

А как насчет MMX / SSE / SSE2?

Думаю, это поможет ... так... decimal - это 128-битный тип данных, а SSE2 тоже 128-битный ... и он может добавлять, sub, div, mul decimal за 1 тик ЦП ...

вы можете написать DLL для SSE2, используя VC ++, а затем использовать эту DLL в своем приложении

например // вы можете сделать что-то вроде этого

VC ++

#include <emmintrin.h>
#include <tmmintrin.h>

extern "C" DllExport __int32* sse2_add(__int32* arr1, __int32* arr2);

extern "C" DllExport __int32* sse2_add(__int32* arr1, __int32* arr2)
{
    __m128i mi1 = _mm_setr_epi32(arr1[0], arr1[1], arr1[2], arr1[3]);
    __m128i mi2 = _mm_setr_epi32(arr2[0], arr2[1], arr2[2], arr2[3]);

    __m128i mi3 = _mm_add_epi32(mi1, mi2);
    __int32 rarr[4] = { mi3.m128i_i32[0], mi3.m128i_i32[1], mi3.m128i_i32[2], mi3.m128i_i32[3] };
    return rarr;
}

C #

[DllImport("sse2.dll")]
private unsafe static extern int[] sse2_add(int[] arr1, int[] arr2);

public unsafe static decimal addDec(decimal d1, decimal d2)
{
    int[] arr1 = decimal.GetBits(d1);
    int[] arr2 = decimal.GetBits(d2);

    int[] resultArr = sse2_add(arr1, arr2);

    return new decimal(resultArr);
}
2
ответ дан 7 November 2019 в 08:02
поделиться

Я не думаю, что инструкции SSE2 могут легко работать с десятичными значениями .NET. Тип данных .NET Decimal - 128-битное десятичное число с плавающей запятой , тип http://en.wikipedia.org/wiki/Decimal128_floating-point_format , инструкции SSE2 работают с 128-битными целочисленными типами .

3
ответ дан 7 November 2019 в 08:02
поделиться

можно использовать длинный тип данных. Несомненно, Вы не будете в состоянии сохранить части там, но если Вы кодируете свое приложение для хранения пенсов вместо фунтов, Вы будете в порядке. Точность составляет 100% для длинных типов данных, и если Вы не работаете с огромными количествами (используйте 64-разрядный длинный тип), Вы будете в порядке.

, Если Вы не можете передать под мандат пенсы хранения, затем оберните целое число в класс и использование это.

41
ответ дан gbjbaanb 7 November 2019 в 18:02
поделиться

Проблема состоит в основном в том, что двойной/плавающий поддерживаются в аппаратных средствах, в то время как Десятичное число и т.п. не. Т.е. необходимо выбрать между скоростью + ограниченная точность и большей точностью + более плохая производительность.

8
ответ дан Brian Rasmussen 7 November 2019 в 18:02
поделиться

Я не могу дать комментарий или провалить все же, так как я только что запустил на переполнении стека. Мой комментарий alexsmart (отправленный 23 декабря 2008 12:31) - то, что выражение Вокруг (n/precision, точность), где n является интервалом и точностью, долго, не сделает то, что он думает:

1) n/precision возвратит целочисленное деление, т.е. он будет уже округлен, но Вы не будете в состоянии использовать любые десятичные числа. Округляющееся поведение также отличается от Математики. Вокруг (...).

2) код" Математика возврата. Вокруг (n/precision, точность).ToString () " не компилирует из-за неоднозначности между Математикой. Вокруг (дважды, интервал) и Математика. Вокруг (десятичное число, интервал). Необходимо будет бросить к десятичному числу (не дважды, так как это - финансовое приложение), и поэтому может также пойти с десятичным числом во-первых.

3) n/precision, то, где точность равняется 4, не усечет к четырем десятичным числам, но разделится на 4. Например, Математика. Вокруг ((десятичное число) (1234567/4), 4) возвраты 308641. (1234567/4 = 308641.75), в то время как то, к чему Вы, вероятно, хотели, становятся 1235000 (округленным к точности 4 цифр от запаздывания 567). Отметьте ту Математику. Вокруг позволяет раунду к фиксированной точке, не фиксированной точности.

Обновление: Я могу добавить комментарии теперь, но существует недостаточно пространства для помещения этого в область комментария.

1
ответ дан ILoveFortran 7 November 2019 в 18:02
поделиться

Вы говорите, что это должно быть быстро, но у Вас есть конкретные требования к скорости? В противном случае можно оптимизировать мимо точки исправности:)

, Поскольку друг, сидящий рядом со мной, только что предложил, можно ли обновить аппаратные средства вместо этого? Это, вероятно, будет более дешевым, чем перезапись кода.

самая очевидная опция состоит в том, чтобы использовать целые числа вместо десятичных чисел - где одна "единица" - что-то как "одна тысячная цента" (или независимо от того, что Вы хотите - Вы получаете идею). Выполнимо ли это или не будет зависеть от операций, Вы выполняете на десятичных значениях для запуска с. Необходимо будет быть очень осторожны при обработке этого - легко сделать ошибки (по крайней мере, если Вы похожи на меня).

профилировщик показывал конкретные горячие точки в Вашем приложении, что Вы могли оптимизировать индивидуально? Например, если необходимо сделать много вычислений в одной небольшой площади кода, Вы могли бы преобразовать от десятичного числа до целочисленного формата, сделать вычисления и затем преобразовать назад. Это могло сохранить API с точки зрения десятичных чисел для объема кода, который может облегчить поддерживать. Однако, если у Вас нет объявленных горячих точек, которые не могут быть выполнимыми.

+1 для профилирования и сообщения нам, что скорость является определенным требованием, btw:)

22
ответ дан Jon Skeet 7 November 2019 в 18:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: