在C#中我有一个double数组(double[]
我的意思是)
我想将所有值四舍五入到C#中的两位小数。
一种解决方案是使用foreach()
和Math.Round()
函数执行此操作
但阵列非常大(1.000.000到10.000.000值)
而不是foreach
,是否有更有效的解决方案?
答案 0 :(得分:8)
而不是foreach,更有效的解决方案?
不。从根本上说,如果要舍入所有值,则必须舍入所有值。没有任何魔法可以使这更简单。
当然,如果您只是要访问一些值,那么您可能会重新设计代码以懒惰访问 - 甚至是显示 - 但如果您确实需要所有值的舍入版本,没有什么能比O(n)操作更快。
你可以按照其他答案中的说法并行执行,这可能会使更快 - 但它会同时比单线程方法更少效率。 (由于所涉及的协调,你最终会做更多的工作 - 但你可能仍然可以更快地完成它。)
您还没有说过为什么要对这些值进行舍入 - 通常,您应该只在显示点处舍入值。你真的确定在此之前需要绕过它们吗?这些价值代表什么? (如果它们是财务价值,您应该强烈考虑decimal
而不是double
。)
答案 1 :(得分:3)
您可以尝试Parallel.Foreach
并将其设为
虽然每个项目仍有操作,但操作不是原子操作,所以你可以这样做。
答案 2 :(得分:2)
我认为没有任何解决方案不包含某种循环。你可以使用LINQ:
array = array.Select(v => Math.Round(v, 2)).ToArray();
但它会比你的自定义for
循环更慢,因为它不会修改数组,而是创建一个带有新值的新数组。
为了让你的循环更快,你可以将它分成几部分并使用TPL同时运行。
答案 3 :(得分:2)
以多线程方式执行此操作:
Parallel.For(0, arr.Length, i => arr[i] = Math.Round(arr[i], 2));
答案 4 :(得分:0)
任何解决方案最终都会转变为循环。虽然你可以很好地写出Linq声明:
rounds = mean.Select(x=>Math.Round(x,2));
如果您有多个处理器,那么可能更快的解决方案是使用Parallel.Foreach
,但您必须对其进行测试以确定它是否确实存在。
答案 5 :(得分: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*/);
});