473,382 Members | 1,431 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,382 software developers and data experts.

anonymous blocks as delegates?

In C# is there any way to use the concept of delegates to have multiple implementations of a particular block of code, so that you can choose between them without the overhead of possibly expensive if() or switch() logic, and without the overhead of a function call?

As an example, consider the task of resizing a bitmap from size X1,Y1 to size X2,Y2 (may be shrunk or expanded, may or may not maintain aspect ratio). Code that handles the general case looks like this:

Bitmap In = new Bitmap(...constructed from a file, let's say),
Out = new Bitmap(X2,Y2);
// BoxW and BoxH represent the size of the patch in the input image that each
// output pixel corresponds to.
int BoxW, BoxH;
BoxW = (Out.Width >= In.Width) ? 1 : (int)((double)In.Width / (double)Out.Width);
BoxH = (Out.Height >= In.Height) ? 1 : (int)((double)In.Height / (double)Out.Height);

double XFactor = (double)In.Width / (double)Out.Width,
YFactor = (double)In.Height / (double)Out.Height;
double R, G, B, // Sums for the color channels.
BoxArea; // not pre-computed because near the edges it may not == BoxW*BoxH.
Color C;
// loop over pixels in the output image,
for(int x = 0; x < Out.Width; x++)
for(int y = 0; y < Out.Height; y++)
{
R = G = B = BoxArea = 0.0;
// sum the R,G,B values of all input pixels in the box
for(int j = 0; j < BoxW; j++)
for(int k = 0; k < BoxH; k++)
if((int)((double)x*XFactor)+j < In.Width &&
(int)((double)y*YFactor)+k < In.Height)
{
C = In.GetPixel((int)((double)x*XFactor)+j,
(int)((double)y*YFactor)+k);
R += (double)(C.R);
G += (double)(C.G);
B += (double)(C.B);
BoxArea++;
}
// set output pixel to average of pixels in the box.
Out.SetPixel(x,y,Color.FromArgb((int)(R / BoxArea),(int)(G / BoxArea),(int)(B / BoxArea)));
}

This works just dandy, but if the output image is bigger than the input image, then BoxW == BoxH == 1, meaning that the above code in that case reduces to:

for(int x = 0; x < Out.Width; x++)
for(int y = 0; y < Out.Height; y++)
{
Out.SetPixel(x,y,In.GetPixel((int)((double)x*XFact or)+j,
(int)((double)y*YFactor)+k));
}

This, clearly, would be much faster. I don't want to do this...

for(int x = 0; x < Out.Width; x++)
for(int y = 0; y < Out.Height; y++)
if(BoxW == BoxH == 1) {
// fast case code
} else {
// general case code
}

....because it's silly to have to evaluate the conditional every time through the inner loop; BoxW and BoxH are loop invariants! I could use delegates to package up the fast case and the general case into separate functions, but then I'm penalized by the overhead of a function call. Is there some way to use delegates in the context of anonymous blocks of code so I could say something like:

// setup:
anonymous_block_delegate_type D;
....
if(BoxW == BoxH == 1) {
D = { Out.SetPixel(x,y,In.GetPixel((int)((double)x*XFact or)+j,
(int)((double)y*YFactor)+k)); }
} else {
D = { // general purpose code }
}
....
for(int x = 0; x < Out.Width; x++)
for(int y = 0; y < Out.Height; y++)
magic_D_invoking_syntax;

That way I could have my cake and eat it too, as it were. Any hope here?
Nov 16 '05 #1
2 1550
you'd still need the same if or switch to determine which block to hook the
delegate up to. and it has to be a method. delegates are like functional
pointers, so without a method, it got nothing to point to.

"Marcos Stefanakopolus" wrote:
In C# is there any way to use the concept of delegates to have multiple implementations of a particular block of code, so that you can choose between them without the overhead of possibly expensive if() or switch() logic, and without the overhead of a function call?

As an example, consider the task of resizing a bitmap from size X1,Y1 to size X2,Y2 (may be shrunk or expanded, may or may not maintain aspect ratio). Code that handles the general case looks like this:

Bitmap In = new Bitmap(...constructed from a file, let's say),
Out = new Bitmap(X2,Y2);
// BoxW and BoxH represent the size of the patch in the input image that each
// output pixel corresponds to.
int BoxW, BoxH;
BoxW = (Out.Width >= In.Width) ? 1 : (int)((double)In.Width / (double)Out.Width);
BoxH = (Out.Height >= In.Height) ? 1 : (int)((double)In.Height / (double)Out.Height);

double XFactor = (double)In.Width / (double)Out.Width,
YFactor = (double)In.Height / (double)Out.Height;
double R, G, B, // Sums for the color channels.
BoxArea; // not pre-computed because near the edges it may not == BoxW*BoxH.
Color C;
// loop over pixels in the output image,
for(int x = 0; x < Out.Width; x++)
for(int y = 0; y < Out.Height; y++)
{
R = G = B = BoxArea = 0.0;
// sum the R,G,B values of all input pixels in the box
for(int j = 0; j < BoxW; j++)
for(int k = 0; k < BoxH; k++)
if((int)((double)x*XFactor)+j < In.Width &&
(int)((double)y*YFactor)+k < In.Height)
{
C = In.GetPixel((int)((double)x*XFactor)+j,
(int)((double)y*YFactor)+k);
R += (double)(C.R);
G += (double)(C.G);
B += (double)(C.B);
BoxArea++;
}
// set output pixel to average of pixels in the box.
Out.SetPixel(x,y,Color.FromArgb((int)(R / BoxArea),(int)(G / BoxArea),(int)(B / BoxArea)));
}

This works just dandy, but if the output image is bigger than the input image, then BoxW == BoxH == 1, meaning that the above code in that case reduces to:

for(int x = 0; x < Out.Width; x++)
for(int y = 0; y < Out.Height; y++)
{
Out.SetPixel(x,y,In.GetPixel((int)((double)x*XFact or)+j,
(int)((double)y*YFactor)+k));
}

This, clearly, would be much faster. I don't want to do this...

for(int x = 0; x < Out.Width; x++)
for(int y = 0; y < Out.Height; y++)
if(BoxW == BoxH == 1) {
// fast case code
} else {
// general case code
}

....because it's silly to have to evaluate the conditional every time through the inner loop; BoxW and BoxH are loop invariants! I could use delegates to package up the fast case and the general case into separate functions, but then I'm penalized by the overhead of a function call. Is there some way to use delegates in the context of anonymous blocks of code so I could say something like:

// setup:
anonymous_block_delegate_type D;
....
if(BoxW == BoxH == 1) {
D = { Out.SetPixel(x,y,In.GetPixel((int)((double)x*XFact or)+j,
(int)((double)y*YFactor)+k)); }
} else {
D = { // general purpose code }
}
....
for(int x = 0; x < Out.Width; x++)
for(int y = 0; y < Out.Height; y++)
magic_D_invoking_syntax;

That way I could have my cake and eat it too, as it were. Any hope here?

Nov 16 '05 #2
> you'd still need the same if or switch to determine which block to hook
the
delegate up to. and it has to be a method. delegates are like functional
pointers, so without a method, it got nothing to point to.
Yes, I know that delegates are used to encapsulate methods, but there are
times (particularly inside deeply nested loops) where incurring method-call
overhead is a bummer. The _concept_ of delegates, as a way to abstractly
represent code that has the same pre- and post-conditions, is what I'm
trying to get at. A delegate is a type-safe pointer-to-method. I want a
generic pointer-to-code that I can use in a similar way, in order to get the
benefits of delegates without the method call overhead.

Thinking more about it from a compiler point of view, it's clear why
associating an actual delegate with an arbitrary block of code isn't going
to work: there are all sorts of issues with getting the variable bindings
inside the block to match what they would be if the block were encountered
"in situ", and of course doing so in a type-safe way would mean having some
sort of syntax for specifying the pre- and post-conditions of the block in
order to use that as the delegate's signature. Perhaps a clearer
explanation of what I'm after would be:

PointerToInstruction target; // a variable indicating which code I want to
execute
if(some_condition)
target = &label1; // pretend for a moment that we can take the address
of a label
else
target = &label2;

for(...)
for(...)
{
goto *target; // abuse C-style "dereference" syntax.
label1: {block 1}
goto label3; // let's not just fall through to block 2.
label2: {block 2}
label3: {} // compiler complains without at least an empty block
}

This way, by the time we get through the C# compiler and the .NET JIT
compiler, that "goto *target" line would get me what I want with an overhead
of one JMP instruction. I could live with that. Of course I can't get the
above structure to work because there's no actual PointerToInstruction type
to declare 'target' to be an instance of (at least, not that I've ever heard
or read about), and the above code uses gotos which are ugly. Is there some
clever way I can use reflection to implement the equivalent of the "goto
*target" line? The ironic thing, of course, is that in raw assembler code
this would be trivial to implement...
"Marcos Stefanakopolus" wrote:
In C# is there any way to use the concept of delegates to have multiple
implementations of a particular block of code, so that you can choose
between them without the overhead of possibly expensive if() or switch()
logic, and without the overhead of a function call?

As an example, consider the task of resizing a bitmap from size X1,Y1 to
size X2,Y2 (may be shrunk or expanded, may or may not maintain aspect
ratio). Code that handles the general case looks like this:

Bitmap In = new Bitmap(...constructed from a file, let's say),
Out = new Bitmap(X2,Y2);
// BoxW and BoxH represent the size of the patch in the input image
that each
// output pixel corresponds to.
int BoxW, BoxH;
BoxW = (Out.Width >= In.Width) ? 1 : (int)((double)In.Width /
(double)Out.Width);
BoxH = (Out.Height >= In.Height) ? 1 : (int)((double)In.Height /
(double)Out.Height);

double XFactor = (double)In.Width / (double)Out.Width,
YFactor = (double)In.Height / (double)Out.Height;
double R, G, B, // Sums for the color channels.
BoxArea; // not pre-computed because near the edges it may not ==
BoxW*BoxH.
Color C;
// loop over pixels in the output image,
for(int x = 0; x < Out.Width; x++)
for(int y = 0; y < Out.Height; y++)
{
R = G = B = BoxArea = 0.0;
// sum the R,G,B values of all input pixels in the box
for(int j = 0; j < BoxW; j++)
for(int k = 0; k < BoxH; k++)
if((int)((double)x*XFactor)+j < In.Width &&
(int)((double)y*YFactor)+k < In.Height)
{
C = In.GetPixel((int)((double)x*XFactor)+j,
(int)((double)y*YFactor)+k);
R += (double)(C.R);
G += (double)(C.G);
B += (double)(C.B);
BoxArea++;
}
// set output pixel to average of pixels in the box.
Out.SetPixel(x,y,Color.FromArgb((int)(R / BoxArea),(int)(G /
BoxArea),(int)(B / BoxArea)));
}

This works just dandy, but if the output image is bigger than the input
image, then BoxW == BoxH == 1, meaning that the above code in that case
reduces to:

for(int x = 0; x < Out.Width; x++)
for(int y = 0; y < Out.Height; y++)
{
Out.SetPixel(x,y,In.GetPixel((int)((double)x*XFact or)+j,
(int)((double)y*YFactor)+k));
}

This, clearly, would be much faster. I don't want to do this...

for(int x = 0; x < Out.Width; x++)
for(int y = 0; y < Out.Height; y++)
if(BoxW == BoxH == 1) {
// fast case code
} else {
// general case code
}

....because it's silly to have to evaluate the conditional every time
through the inner loop; BoxW and BoxH are loop invariants! I could use
delegates to package up the fast case and the general case into separate
functions, but then I'm penalized by the overhead of a function call. Is
there some way to use delegates in the context of anonymous blocks of
code so I could say something like:

// setup:
anonymous_block_delegate_type D;
....
if(BoxW == BoxH == 1) {
D = { Out.SetPixel(x,y,In.GetPixel((int)((double)x*XFact or)+j,
(int)((double)y*YFactor)+k)); }
} else {
D = { // general purpose code }
}
....
for(int x = 0; x < Out.Width; x++)
for(int y = 0; y < Out.Height; y++)
magic_D_invoking_syntax;

That way I could have my cake and eat it too, as it were. Any hope here?

Nov 16 '05 #3

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

20
by: Doug Holton | last post by:
Is there any metaclass trick or something similar to allow anonymous code blocks? I'd like to be able to let users do something like this fictitious example: b = Button() b.OnClick =: print...
5
by: Steve Murphy | last post by:
I have a couple of standard Try/Catch blocks that I use repeatedly. Is there anyway to wrap these blocks into a method call? Or does C# have anything like a C++ macro? Thanks, Steve Murphy
3
by: anonymous | last post by:
I believe I ran into an interesting way to create memory leaks in C# 2.0 using anymous delegates. Here is a sample of the code in question. private void Handle_Event(object sender, EventArgs e)...
5
by: cody | last post by:
I have a very funny/strange effect here. if I let the delegate do "return prop.GetGetMethod().Invoke(info.AudioHeader, null);" then I get wrong results, that is, a wrong method is called and I...
7
by: moondaddy | last post by:
I'm reading the book Wrox-Professional C# 2005 and it's trying to demonstrate an anonymous method in an event handler. I would not do this in a real app, but am trying to understand how this...
7
by: Bill Woodruff | last post by:
I've found it's no problem to insert instances of named delegates as values into a generic dictionary of the form : private Dictionary<KeyType, DelegatemyDictionary = new Dictionary<KeyType,...
15
by: Matt | last post by:
Hi There, Can anyone explain me the real advantages of (other than syntax) lambda expressions over anonymous delegates? advantage for one over the other. delegate int F(int a); F fLambda = a...
4
by: Frankie | last post by:
I have just gotten up to speed on what anonymous methods are (syntax, capabilities, etc), and how they can be used with /called via delegates. What I am wondering is... 1. Are they only/mostly...
1
by: ktrvnbq02 | last post by:
Hi, I recently came to debug some old code that was causing a StackOverflowException. The code in question makes significant use of recursion and with large data structures it exhausted the...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.