阵列性能不佳 [英] Poor array performance

查看:76
本文介绍了阵列性能不佳的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个客户打电话给他们已经放在一起的一些C#代码,这些代码是处理一些大型数组的。表现相当差。 C#代码

运行大约22秒,等效的C ++ .Net代码运行0.3

秒。有人可以帮我理解为什么C#代码表现如此可怜b $ b差吗?我将C#代码重新命名为使用单个维数阵列,时间

下降到大约3秒,但是仍然没有解释为什么

2维度阵列表现如此糟糕。我在C#1.1和

C#2.0上试过这个。

原始代码是:


public void TestLoop4OldMethod()

{

double [,] emisbase = new double [1000,8784];

double [,] vombase = new double [1000,8784] ];

int Iteration_Index;

int Hourly_Index;

double differenceInSeconds;

DateTime myDateTime1;

DateTime myDateTime2;


myDateTime1 = DateTime.UtcNow;

for(int i1 = 0; i1< 10;)

{

for(Hourly_Index = 0; Hourly_Index< 8784;)

{

for(Iteration_Index = 0; Iteration_Index< ; 1000;)

{

emisbase [Iteration_Index,Hourly_Index] = Iteration_Index *

Iteration_Index;

vombase [ Iteration_Index,Hourly_Index] = emisbase [Iteration_Index,

Iteration_Index];

Iteration_Index ++;

}

Hourly_Index ++; < br $>
}

//Console.WriteLine( 我们在这里 - 循环4:{0},i1);

i1 ++;

}

myDateTime2 = DateTime.UtcNow ;

TimeSpan ts = myDateTime2 - myDateTime1;

differenceInSeconds = ts.TotalMilliseconds / 1000;


Console.WriteLine(" RunTime in Seconds - Left Most Index + array

reference:{0}",differenceInSeconds);

Console.WriteLine(" );

}

它运行大约22秒。在这里,我用C ++重写了代码,它运行在

0.3秒内:

// ------------------ -------------------------------------------------- -----

------------------------------------- ------

int Iteration_Index;

int Hourly_Index;

double differenceInSeconds;

DateTime myDateTime1;

DateTime myDateTime2;


double * emisbase = new double [1000,8784];

double * vombase = new double [ 1000,8784];


myDateTime1 = DateTime :: UtcNow;

for(int i1 = 0; i1< 10;)

{

for(Hourly_Index = 0; Hourly_Index< 8784; Hourly_Index ++)

{

for(Iteration_Index = 0; Iteration_Index< ; 1000; Iteration_Index ++)

{

emisbase [Iteration_Index,Hourly_Index] = Iteration_Index *

Iteration_Index;

vombase [Iteration_Index,Hourly_Index] = emisbase [Iteration_Index,

Iteration_Index];

// Iteration_Index ++;

}

// Hourly_Index ++;

}

//控制台::写(S"这里我们是 - 循环4:);

// Console :: WriteLine(Convert :: ToString(i1));

i1 ++;

}

myDateTime2 = DateTime :: UtcNow;

TimeSpan ts = myDateTime2 - myDateTime1;

differenceInSeconds = ts.TotalMilliseconds / 1000;


控制台::写(S" RunTime in Seconds - Left Most Index + array reference:

");

Console :: WriteLine(Convert :: ToString(differenceInS econds));


// ---------------------- -------------------------------------------------- -

----------------------------------------- -

I had a customer call about some C# code they had put together that was
handling some large arrays. The performance was rather poor. The C# code
runs in about 22 seconds and the equivalent C++.Net code runs in 0.3
seconds. Can someone help me understand why the C# code performance is so
poor? I rewote the C# code to use a single dimenional array and the time
went down to about 3 seconds, but that''s still no explaination as to why the
two dimenional array performance is so bad. I tried this on both C# 1.1 and
C# 2.0.
The original code was:

public void TestLoop4OldMethod()
{
double[,] emisbase = new double[1000,8784];
double[,] vombase = new double[1000,8784];
int Iteration_Index;
int Hourly_Index;
double differenceInSeconds;
DateTime myDateTime1;
DateTime myDateTime2;

myDateTime1 = DateTime.UtcNow;
for (int i1 = 0; i1 < 10; )
{
for (Hourly_Index = 0; Hourly_Index < 8784; )
{
for (Iteration_Index = 0; Iteration_Index < 1000; )
{
emisbase[Iteration_Index, Hourly_Index] = Iteration_Index *
Iteration_Index;
vombase[Iteration_Index, Hourly_Index] = emisbase[Iteration_Index,
Iteration_Index];
Iteration_Index++;
}
Hourly_Index++;
}
//Console.WriteLine("Here we are - Loop 4: {0}", i1);
i1++;
}
myDateTime2 = DateTime.UtcNow;
TimeSpan ts = myDateTime2 - myDateTime1;
differenceInSeconds = ts.TotalMilliseconds / 1000;

Console.WriteLine("RunTime in Seconds - Left Most Index + array
reference: {0} ", differenceInSeconds);
Console.WriteLine(" ");
}
It runs in about 22 seconds. Here I rewrote the code in C++ and it runs in
0.3 seconds:
// -------------------------------------------------------------------------
-------------------------------------------
int Iteration_Index;
int Hourly_Index;
double differenceInSeconds;
DateTime myDateTime1;
DateTime myDateTime2;

double * emisbase = new double[1000,8784];
double * vombase = new double[1000,8784];

myDateTime1 = DateTime::UtcNow;
for (int i1 = 0; i1 < 10; )
{
for (Hourly_Index = 0; Hourly_Index < 8784; Hourly_Index++)
{
for (Iteration_Index = 0; Iteration_Index < 1000; Iteration_Index++)
{
emisbase[Iteration_Index, Hourly_Index] = Iteration_Index *
Iteration_Index;
vombase[Iteration_Index, Hourly_Index] = emisbase[Iteration_Index,
Iteration_Index];
//Iteration_Index++;
}
//Hourly_Index++;
}
//Console::Write(S"Here we are - Loop 4: ");
//Console::WriteLine(Convert::ToString(i1));
i1++;
}
myDateTime2 = DateTime::UtcNow;
TimeSpan ts = myDateTime2 - myDateTime1;
differenceInSeconds = ts.TotalMilliseconds / 1000;

Console::Write(S"RunTime in Seconds - Left Most Index + array reference:
");
Console::WriteLine(Convert::ToString(differenceInS econds));

// -------------------------------------------------------------------------
-------------------------------------------

推荐答案

对于一个运行近900万次的循环,3秒也不错! ;-)


我不知道C#的内部结构是否足以说明它的智能

,但为什么不留在托管C ++中部分?这听起来像这是一个关键的部分,无论如何应该优化它......

" John Mark Howell" < JM ********* @ hotmail.com>在留言中写道

新闻:%2 **************** @ TK2MSFTNGP12.phx.gbl ...
For a loop that runs almost 9 million times, 3 seconds is not that bad! ;-)

I don''t know the internals of C# well enough to say something intelligent
about it, but why not leave in the managed C++ part? It sounds like this is
a critical section that should have the heck optimized out of it anyhow...
"John Mark Howell" <jm*********@hotmail.com> wrote in message
news:%2****************@TK2MSFTNGP12.phx.gbl...
我有客户打电话询问他们放在一起的一些C#代码,这些代码处理了一些大型数组。表现相当差。 C#
代码运行大约22秒,等效的C ++ .Net代码运行0.3
秒。有人能帮助我理解为什么C#代码性能如此差劲?我将C#代码改写为使用单个维数阵列,并且
时间下降到大约3秒,但是仍然没有解释为什么

两个维度阵列表现如此糟糕。我在C#1.1和/或C#2.0上试过这个。

原始代码是:

public void TestLoop4OldMethod()
{
double [,] emisbase = new double [1000,8784];
double [,] vombase = new double [1000,8784];
int Iteration_Index;
int Hourly_Index;
double differenceInSeconds;
DateTime myDateTime1;
DateTime myDateTime2;

myDateTime1 = DateTime.UtcNow;
for(int i1 = 0; i1< 10 ;)
{
for(Hourly_Index = 0; Hourly_Index< 8784;)
{
for(Iteration_Index = 0; Iteration_Index< 1000;)
{
emisbase [Iteration_Index,Hourly_Index] = Iteration_Index *
Iteration_Index;
vombase [Iteration_Index,Hourly_Index] = emisbase [Iteration_Index,
Iteration_Index];
Iteration_Index ++;
}
每小时_索引++;
} //Console.WriteLine("Here we are - Loop 4:{0}",i1);
i1 ++; }
myDateTime2 = DateTime.UtcNow;
TimeSpan ts = myDateTime2 - myDateTime1;
differenceInSeconds = ts.TotalMilliseconds / 1000;

Console.WriteLine(" ; RunTime in Seconds - Left Most Index + array
reference:{0}",differenceInSeconds);
Console.WriteLine(") );
}

它运行大约22秒。在这里,我用C ++重写代码,它在
0.3秒内运行


// ------------------ -------------------------------------------------- -----
----------------------------------------- -
int Iteration_Index;
int Hourly_Index;
double differenceInSeconds;
DateTime myDateTime1;
DateTime myDateTime2;

double * emisbase = new double [1000,8784];
double * vombase = new double [1000,8784];

myDateTime1 = DateTime :: UtcNow;
for(int i1 = 0; i1 < 10;)
{
for(Hourly_Index = 0; Hourly_Index< 8784; Hourly_Index ++)
{
for(Iteration_Index = 0; Iteration_Index< 1000; Iteration_Index ++)
{
emisbase [Iteration_Index,Hourly_Index] = Iteration_Index *
Iteration_Index;
vombase [Iteration_Index,Hourly_Index] = emisbase [Iteration_Index,
Iteration_Index];
/ / Iteration_Index ++;
}
// Hourly_Index ++;
}
//控制台:: Wri te(S" Here we are - Loop 4:");
// Console :: WriteLine(Convert :: ToString(i1));
i1 ++;
}
myDateTime2 = DateTime :: UtcNow;
TimeSpan ts = myDateTime2 - myDateTime1;
differenceInSeconds = ts.TotalMilliseconds / 1000;

Console :: Write(S" RunTime in Seconds - Left大多数Index +数组引用:
");
Console :: WriteLine(Convert :: ToString(differenceInS econds));

// ------- -------------------------------------------------- ----------------
------------------------------ -------------

I had a customer call about some C# code they had put together that was
handling some large arrays. The performance was rather poor. The C#
code
runs in about 22 seconds and the equivalent C++.Net code runs in 0.3
seconds. Can someone help me understand why the C# code performance is so
poor? I rewote the C# code to use a single dimenional array and the
time
went down to about 3 seconds, but that''s still no explaination as to why
the
two dimenional array performance is so bad. I tried this on both C# 1.1
and
C# 2.0.
The original code was:

public void TestLoop4OldMethod()
{
double[,] emisbase = new double[1000,8784];
double[,] vombase = new double[1000,8784];
int Iteration_Index;
int Hourly_Index;
double differenceInSeconds;
DateTime myDateTime1;
DateTime myDateTime2;

myDateTime1 = DateTime.UtcNow;
for (int i1 = 0; i1 < 10; )
{
for (Hourly_Index = 0; Hourly_Index < 8784; )
{
for (Iteration_Index = 0; Iteration_Index < 1000; )
{
emisbase[Iteration_Index, Hourly_Index] = Iteration_Index *
Iteration_Index;
vombase[Iteration_Index, Hourly_Index] = emisbase[Iteration_Index,
Iteration_Index];
Iteration_Index++;
}
Hourly_Index++;
}
//Console.WriteLine("Here we are - Loop 4: {0}", i1);
i1++;
}
myDateTime2 = DateTime.UtcNow;
TimeSpan ts = myDateTime2 - myDateTime1;
differenceInSeconds = ts.TotalMilliseconds / 1000;

Console.WriteLine("RunTime in Seconds - Left Most Index + array
reference: {0} ", differenceInSeconds);
Console.WriteLine(" ");
}
It runs in about 22 seconds. Here I rewrote the code in C++ and it runs
in
0.3 seconds:
// -------------------------------------------------------------------------
-------------------------------------------
int Iteration_Index;
int Hourly_Index;
double differenceInSeconds;
DateTime myDateTime1;
DateTime myDateTime2;

double * emisbase = new double[1000,8784];
double * vombase = new double[1000,8784];

myDateTime1 = DateTime::UtcNow;
for (int i1 = 0; i1 < 10; )
{
for (Hourly_Index = 0; Hourly_Index < 8784; Hourly_Index++)
{
for (Iteration_Index = 0; Iteration_Index < 1000; Iteration_Index++)
{
emisbase[Iteration_Index, Hourly_Index] = Iteration_Index *
Iteration_Index;
vombase[Iteration_Index, Hourly_Index] = emisbase[Iteration_Index,
Iteration_Index];
//Iteration_Index++;
}
//Hourly_Index++;
}
//Console::Write(S"Here we are - Loop 4: ");
//Console::WriteLine(Convert::ToString(i1));
i1++;
}
myDateTime2 = DateTime::UtcNow;
TimeSpan ts = myDateTime2 - myDateTime1;
differenceInSeconds = ts.TotalMilliseconds / 1000;

Console::Write(S"RunTime in Seconds - Left Most Index + array reference:
");
Console::WriteLine(Convert::ToString(differenceInS econds));

// -------------------------------------------------------------------------
-------------------------------------------



你运行循环多少次了?第一次执行代码时,它必须是JIT编译的,并且可能需要花费一些时间。


只是一个想法。

How many times did you run the loop? The first time the code is
executed it must be JIT compiled and that can take some of the time.

Just a thought.


快吧,但是对吗?运行这种

基准测试时,一个重要的事情是结果是正确且可重复的(我的意思是

时间和执行操作的结果)。 />
您是否检查了数组元素的值(比如前10个位置)
运行后的


IMO他们不正确C ++的情况。

当我找到一些空闲时间时,我将看一下代码,但是
Fast right, but correct? One important thing when running such kind of
benchmark is that the results are correct and repeatable (and I mean the
timing and the results of the operations performed).
Did you inspect the value of the array elements (say the first 10 locations)
after the run?
IMO they aren''t correct in case of C++.
I will take a look at the code when I find some spare time, but 0.3 sec for
0.3秒时,我会查看代码,80%的迭代闻起来像破坏的优化。
80 Million iterations smell like "broken optimization".




Willy。


" John Mark Howell" < JM ********* @ hotmail.com>在消息中写道

新闻:%2 **************** @ TK2MSFTNGP12.phx.gbl ...

| I有一个客户打电话给他们放在一起的一些C#代码是

|处理一些大型数组。表现相当差。 C#

代码

|运行大约22秒,等效的C ++ .Net代码运行在0.3

|秒。有人可以帮我理解为什么C#代码表现如此

|较差的?我重写了C#代码,使用单个维数阵列和

时间

|下降到大约3秒钟,但是仍然没有解释为什么



|二维阵列性能如此糟糕。我在C#1.1



|上尝试了这个C#2.0。

|

|

|原始代码是:

|

| public void TestLoop4OldMethod()

| {

| double [,] emisbase = new double [1000,8784];

| double [,] vombase = new double [1000,8784];

| int Iteration_Index;

| int Hourly_Index;

| double differenceInSeconds;

| DateTime myDateTime1;

| DateTime myDateTime2;

|

| myDateTime1 = DateTime.UtcNow;

| for(int i1 = 0; i1< 10;)

| {

| for(Hourly_Index = 0; Hourly_Index< 8784;)

| {

| for(Iteration_Index = 0; Iteration_Index< 1000;)

| {

| emisbase [Iteration_Index,Hourly_Index] = Iteration_Index *

| Iteration_Index;

| vombase [Iteration_Index,Hourly_Index] = emisbase [Iteration_Index,

| Iteration_Index];

| Iteration_Index ++;

| }

| Hourly_Index ++;

| }

| //Console.WriteLine("Here we are - Loop 4:{0}",i1);

| i1 ++;

| }

| myDateTime2 = DateTime.UtcNow;

| TimeSpan ts = myDateTime2 - myDateTime1;

| differenceInSeconds = ts.TotalMilliseconds / 1000;

|

| Console.WriteLine(RunTime in Seconds - Left Most Index + array

| reference:{0},differenceInSeconds);

| Console.WriteLine("");

| }

|

|

|它运行大约22秒。在这里,我用C ++重写代码,它在

|中运行

0.3秒:

|

|

|

// ---------- -------------------------------------------------- -------------

| -------------------------------------------

| int Iteration_Index;

| int Hourly_Index;

| double differenceInSeconds;

| DateTime myDateTime1;

| DateTime myDateTime2;

|

| double * emisbase = new double [1000,8784];

| double * vombase = new double [1000,8784];

|

| myDateTime1 = DateTime :: UtcNow;

| for(int i1 = 0; i1< 10;)

| {

| for(Hourly_Index = 0; Hourly_Index< 8784; Hourly_Index ++)

| {

| for(Iteration_Index = 0; Iteration_Index< 1000; Iteration_Index ++)

| {

| emisbase [Iteration_Index,Hourly_Index] = Iteration_Index *

| Iteration_Index;

| vombase [Iteration_Index,Hourly_Index] = emisbase [Iteration_Index,

| Iteration_Index];

| // Iteration_Index ++;

| }

| // Hourly_Index ++;

| }

| // Console :: Write(S" Here are-Loop 4:");

| // Console :: WriteLine(Convert :: ToString(i1));

| i1 ++;

| }

| myDateTime2 = DateTime :: UtcNow;

| TimeSpan ts = myDateTime2 - myDateTime1;

| differenceInSeconds = ts.TotalMilliseconds / 1000;

|

| Console :: Write(S" RunTime in Seconds - Left Most Index + array reference:

|");

| Console :: WriteLine(Convert :: ToString(differenceInS econds));

|

|

// ------- -------------------------------------------------- ----------------

| -------------------------------------------

|

|

|

|

|



Willy.


"John Mark Howell" <jm*********@hotmail.com> wrote in message
news:%2****************@TK2MSFTNGP12.phx.gbl...
|I had a customer call about some C# code they had put together that was
| handling some large arrays. The performance was rather poor. The C#
code
| runs in about 22 seconds and the equivalent C++.Net code runs in 0.3
| seconds. Can someone help me understand why the C# code performance is so
| poor? I rewote the C# code to use a single dimenional array and the
time
| went down to about 3 seconds, but that''s still no explaination as to why
the
| two dimenional array performance is so bad. I tried this on both C# 1.1
and
| C# 2.0.
|
|
| The original code was:
|
| public void TestLoop4OldMethod()
| {
| double[,] emisbase = new double[1000,8784];
| double[,] vombase = new double[1000,8784];
| int Iteration_Index;
| int Hourly_Index;
| double differenceInSeconds;
| DateTime myDateTime1;
| DateTime myDateTime2;
|
| myDateTime1 = DateTime.UtcNow;
| for (int i1 = 0; i1 < 10; )
| {
| for (Hourly_Index = 0; Hourly_Index < 8784; )
| {
| for (Iteration_Index = 0; Iteration_Index < 1000; )
| {
| emisbase[Iteration_Index, Hourly_Index] = Iteration_Index *
| Iteration_Index;
| vombase[Iteration_Index, Hourly_Index] = emisbase[Iteration_Index,
| Iteration_Index];
| Iteration_Index++;
| }
| Hourly_Index++;
| }
| //Console.WriteLine("Here we are - Loop 4: {0}", i1);
| i1++;
| }
| myDateTime2 = DateTime.UtcNow;
| TimeSpan ts = myDateTime2 - myDateTime1;
| differenceInSeconds = ts.TotalMilliseconds / 1000;
|
| Console.WriteLine("RunTime in Seconds - Left Most Index + array
| reference: {0} ", differenceInSeconds);
| Console.WriteLine(" ");
| }
|
|
| It runs in about 22 seconds. Here I rewrote the code in C++ and it runs
in
| 0.3 seconds:
|
|
|
// -------------------------------------------------------------------------
| -------------------------------------------
| int Iteration_Index;
| int Hourly_Index;
| double differenceInSeconds;
| DateTime myDateTime1;
| DateTime myDateTime2;
|
| double * emisbase = new double[1000,8784];
| double * vombase = new double[1000,8784];
|
| myDateTime1 = DateTime::UtcNow;
| for (int i1 = 0; i1 < 10; )
| {
| for (Hourly_Index = 0; Hourly_Index < 8784; Hourly_Index++)
| {
| for (Iteration_Index = 0; Iteration_Index < 1000; Iteration_Index++)
| {
| emisbase[Iteration_Index, Hourly_Index] = Iteration_Index *
| Iteration_Index;
| vombase[Iteration_Index, Hourly_Index] = emisbase[Iteration_Index,
| Iteration_Index];
| //Iteration_Index++;
| }
| //Hourly_Index++;
| }
| //Console::Write(S"Here we are - Loop 4: ");
| //Console::WriteLine(Convert::ToString(i1));
| i1++;
| }
| myDateTime2 = DateTime::UtcNow;
| TimeSpan ts = myDateTime2 - myDateTime1;
| differenceInSeconds = ts.TotalMilliseconds / 1000;
|
| Console::Write(S"RunTime in Seconds - Left Most Index + array reference:
| ");
| Console::WriteLine(Convert::ToString(differenceInS econds));
|
|
// -------------------------------------------------------------------------
| -------------------------------------------
|
|
|
|
|


这篇关于阵列性能不佳的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆