2013-11-27 2 views
1

В C# у меня есть массив double (double[]) Я хочу округлить все значения до двух знаков после запятой в C#.Как рассчитать раунд на очень большом массиве двойных в C#

Одно из решений, чтобы сделать это с foreach() и Math.Round() функций но массив очень большой (1.000.000 до 10.000.000 значения)

Вместо foreach, есть более эффективное решение?

+2

ли тест на округление 10.000.000 пунктов, потребовалось ~ 300 мс, так что если вы должны сделать эту операцию очень часто ее не отнимать много времени. – Magnus

ответ

2

Чтобы сделать это в многопоточном образом:

Parallel.For(0, arr.Length, i => arr[i] = Math.Round(arr[i], 2)); 
+0

спасибо за вашу помощь .... Я попробую это – LeMoussel

3

Вы можете попробовать Parallel.Foreach и нить его

Хотя есть еще работа за единицу, то операции не являются атомарными, так что вы можете сделать это.

2

Я не думаю, что есть какое-либо решение, которое не включает какой-то цикл. Вы можете использовать LINQ:

array = array.Select(v => Math.Round(v, 2)).ToArray(); 

, но это будет еще медленнее, чем ваш цикл пользовательских for, потому что вместо изменения массива на месте, он будет создавать новый с новыми значениями.

Чтобы сделать ваш цикл быстрее, вы можете разбить его на части и запустить одновременно, используя TPL.

8

Вместо foreach более эффективное решение?

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

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

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

Вы ничего не сказали о том, почему вы хотите округлить эти значения, Как правило, вы должны только округлять значения в точке отображения. Вы действительно уверены, что вам нужно округлить их до этого? Что представляют значения? (Если они представляют собой финансовые значения, вы должны строго рассмотреть decimal вместо double.)

0

Любое решение в конечном итоге переходит в цикл. Хотя вы можете написать красиво, как заявление Linq:

rounds = mean.Select(x=>Math.Round(x,2)); 

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

0

Да, вы можете использовать Parallel.ForEach.

List<Double> values; 
//fill list 

ConcurrentBag<Double> rounded = new ConcurrentBag<Double>(); 

Parallel.ForEach(
    values, 
    value => 
    {  
    rounded.Add(/*value rounded to 2 decimal places*/); 
    }); 
Смежные вопросы