1. Why I need to use C for screen graphics

I would love to have my application be 100% Euphoria, since it claims to be such
a fast language. However, I have to do some work in C because Euphoria is too
slow. Euphoria is okay most of the time. But here is an example where compiled C
is 20 times faster. I wrote a test case to prove it.
--  code generated by Win32Lib IDE v1.0.0 Build Apr-26-2007

constant TheProgramType="exw" 
 
include Win32Lib.ew
without warning

--------------------------------------------------------------------------------
--  Window Window1
constant Window1 = createEx( Window, "Test to compare Euphoria and C graphics",
0, Default, Default, 800, 600, 0, 0 )
constant DRAWIN = createEx( Window, "", Window1, 152, 0, 510, 510, {WS_CHILD,
WS_CLIPSIBLINGS, WS_DLGFRAME}, {WS_EX_CLIENTEDGE, WS_EX_STATICEDGE} )
openWindow(DRAWIN, Normal)
moveZOrder( DRAWIN, HWND_TOP)
setWindowBackColor( DRAWIN,16777215 )
constant RUNE = createEx( PushButton, "RUN Euphoria", Window1, 28, 28, 88, 28,
0, 0 )
constant RUNC = createEx( PushButton, "Run C", Window1, 28, 68, 88, 28, 0, 0 )
---------------------------------------------------------
--------------------------------------------------------------------------------
include dll.e -- this is for calling draw_magic in C
include machine.e -- this is for the container to pass to C a structure

constant backcolor = #FFFFFF -- white

atom draw_dll
integer draw_C -- C routine handle for Euphoria

draw_dll = open_dll ("DRAWtest.dll")
draw_C = define_c_proc (draw_dll, "_draw_test@4", {C_UINT})
-- in C this would be: VOID draw_test(HDC hDC)
-- assume device context is a UINT and draw_test has the form Watcom created in
the DLL.
if draw_C = -1 then
    abortErr(  "Draw function not found" )
end if

--------------------------------------------------------------------------------
procedure RUNE_onClick (integer self, integer event, sequence params)--params is
()
-- run Euphoria drawing

integer x,y
atom t0
integer MsgBox
t0 = time()

setWindowBackColor( DRAWIN, backcolor )
setPenMode( DRAWIN, R2_COPYPEN )
setPenColor( DRAWIN, 0 )

set_rand(1500)
for i=1 to 100000 do
	x = rand(500)
	y = rand(500)
	drawLine ( DRAWIN, x, y, x, y+2 )
end for

MsgBox = message_box(sprintf("Took %f time",{time()-t0}),"Test Euphoria", #0)

end procedure
setHandler( RUNE, w32HClick, routine_id("RUNE_onClick"))
--------------------------------------------------------------------------------
procedure RUNC_onClick (integer self, integer event, sequence params)--params is
()
-- Run the C test

atom hDC

atom t0
integer MsgBox
t0 = time()

setWindowBackColor( DRAWIN, backcolor )
hDC = getDC (DRAWIN)
c_proc (draw_C, {hDC})
releaseDC (hDC)

MsgBox = message_box(sprintf("Took %f time",{time()-t0}),"Test C", #0)

end procedure
setHandler( RUNC, w32HClick, routine_id("RUNC_onClick"))


WinMain( Window1,Normal )


C code: (I wonder how it is going to look inside of eucode tags)
#define STRICT
#include <math.h>
#include <windows.h>
#include <stdlib.h>

VOID __stdcall __export draw_test(HDC hDC)
{
	int i,x,y;

	HPEN hcolorpen;
	hcolorpen = CreatePen(PS_SOLID,0,0);
	SetROP2(hDC, R2_COPYPEN);   // drawing mode
	SelectObject(hDC,hcolorpen);

	srand(1500);
	for (i=0; i<100000; i++)
	{
		x = rand()%500;
		y = rand()%500;
		MoveToEx( hDC, x, y, NULL );
		LineTo( hDC, x, y+2 );
	}

	DeleteObject(hcolorpen);
}


Andy Katz
B.S. Computer Science, 1978
Rensselaer Polytechnic Institute (RPI)

new topic     » topic index » view message » categorize

2. Re: Why I need to use C for screen graphics

There are indeed cases where Euphoria is simply too slow. But this is not one of
them. The performance bottleneck here is the Win32Lib function drawLine(). This
function is convenient to use but it is not fast. It calls getDC(), createPen(),
and releaseDC() for every line drawn. I modified the RUNE_onClick() procedure as
follows:

procedure RUNE_onClick (integer self, integer event, sequence params)--params is
()
-- run Euphoria drawing

integer x,y,PS_SOLID
atom t0,hDC,hPen,void,hOldPen
integer MsgBox
t0 = time()
PS_SOLID=0

setWindowBackColor( DRAWIN, backcolor )

set_rand(1500)
hDC=getDC(DRAWIN)
hPen=w32Func(xCreatePen,{PS_SOLID,1,Black})
hOldPen=w32Func(xSelectObject,{hDC,hPen})
for i=1 to 100000 do
	x = rand(500)
	y = rand(500)
	void=w32Func(xMoveToEx,{hDC,x,y,0})
	void=w32Func(xLineTo,{hDC,x,y+2})
end for
void=w32Func(xSelectObject,{hDC,hOldPen})
void=w32Func(xDeleteObject,{hPen})
releaseDC(RUNE)

MsgBox = message_box(sprintf("Took %f time",{time()-t0}),"Test Euphoria", #0)

end procedure
setHandler( RUNE, w32HClick, routine_id("RUNE_onClick"))


The speed improvement was dramatic. The original code executed in about 12
seconds on my machine. The modified version took only .75 seconds.

Larry Miller

new topic     » goto parent     » topic index » view message » categorize

3. Re: Why I need to use C for screen graphics

Andrew Katz wrote:

> I would love to have my application be 100% Euphoria, since it claims to be
> such a fast language. However, I have to do some work in C because Euphoria
> is too slow. Euphoria is okay most of the time. But here is an example where
> compiled C is 20 times faster. I wrote a test case to prove it.

[Code snipped]

Did you _compile_ the Euphoria code?
Your Euphoria code and your C code is not comparable, see Larry's post.

Regards,
   Juergen

new topic     » goto parent     » topic index » view message » categorize

4. Re: Why I need to use C for screen graphics

Andrew Katz wrote:
> 
> I would love to have my application be 100% Euphoria, since it claims to be
> such a fast language. However, I have to do some work in C because Euphoria
> is too slow. Euphoria is okay most of the time. But here is an example where
> compiled C is 20 times faster. I wrote a test case to prove it.
> }}}
<eucode>
> --  code generated by Win32Lib IDE v1.0.0 Build Apr-26-2007
> 
> constant TheProgramType="exw" 
>  
> include Win32Lib.ew
> without warning
> 
>
> --------------------------------------------------------------------------------
> --  Window Window1
> constant Window1 = createEx( Window, "Test to compare Euphoria and C
> graphics", 0, Default, Default, 800,
> 600, 0, 0 )
> constant DRAWIN = createEx( Window, "", Window1, 152, 0, 510, 510, {WS_CHILD,
> WS_CLIPSIBLINGS, WS_DLGFRAME},
> {WS_EX_CLIENTEDGE, WS_EX_STATICEDGE} )
> openWindow(DRAWIN, Normal)
> moveZOrder( DRAWIN, HWND_TOP)
> setWindowBackColor( DRAWIN,16777215 )
> constant RUNE = createEx( PushButton, "RUN Euphoria", Window1, 28, 28, 88, 28,
> 0, 0 )
> constant RUNC = createEx( PushButton, "Run C", Window1, 28, 68, 88, 28, 0, 0 )
> ---------------------------------------------------------
>
> --------------------------------------------------------------------------------
> include dll.e -- this is for calling draw_magic in C
> include machine.e -- this is for the container to pass to C a structure
> 
> constant backcolor = #FFFFFF -- white
> 
> atom draw_dll
> integer draw_C -- C routine handle for Euphoria
> 
> draw_dll = open_dll ("DRAWtest.dll")
> draw_C = define_c_proc (draw_dll, "_draw_test@4", {C_UINT})
> -- in C this would be: VOID draw_test(HDC hDC)
> -- assume device context is a UINT and draw_test has the form Watcom created
> in the DLL.
> if draw_C = -1 then
>     abortErr(  "Draw function not found" )
> end if
> 
>
> --------------------------------------------------------------------------------
> procedure RUNE_onClick (integer self, integer event, sequence params)--params
> is ()
> -- run Euphoria drawing
> 
> integer x,y
> atom t0
> integer MsgBox
> t0 = time()
> 
> setWindowBackColor( DRAWIN, backcolor )
> setPenMode( DRAWIN, R2_COPYPEN )
> setPenColor( DRAWIN, 0 )
> 
> set_rand(1500)
> for i=1 to 100000 do
> 	x = rand(500)
> 	y = rand(500)
> 	drawLine ( DRAWIN, x, y, x, y+2 )
> end for
> 
> MsgBox = message_box(sprintf("Took %f time",{time()-t0}),"Test Euphoria", #0)
> 
> end procedure
> setHandler( RUNE, w32HClick, routine_id("RUNE_onClick"))
>
> --------------------------------------------------------------------------------
> procedure RUNC_onClick (integer self, integer event, sequence params)--params
> is ()
> -- Run the C test
> 
> atom hDC
> 
> atom t0
> integer MsgBox
> t0 = time()
> 
> setWindowBackColor( DRAWIN, backcolor )
> hDC = getDC (DRAWIN)
> c_proc (draw_C, {hDC})
> releaseDC (hDC)
> 
> MsgBox = message_box(sprintf("Took %f time",{time()-t0}),"Test C", #0)
> 
> end procedure
> setHandler( RUNC, w32HClick, routine_id("RUNC_onClick"))
> 
> 
> WinMain( Window1,Normal )
> </eucode>
{{{

> 
> C code: (I wonder how it is going to look inside of eucode tags)
> }}}
<eucode>
> #define STRICT
> #include <math.h>
> #include <windows.h>
> #include <stdlib.h>
> 
> VOID __stdcall __export draw_test(HDC hDC)
> {
> 	int i,x,y;
> 
> 	HPEN hcolorpen;
> 	hcolorpen = CreatePen(PS_SOLID,0,0);
> 	SetROP2(hDC, R2_COPYPEN);   // drawing mode
> 	SelectObject(hDC,hcolorpen);
> 
> 	srand(1500);
> 	for (i=0; i<100000; i++)
> 	{
> 		x = rand()%500;
> 		y = rand()%500;
> 		MoveToEx( hDC, x, y, NULL );
> 		LineTo( hDC, x, y+2 );
> 	}
> 
> 	DeleteObject(hcolorpen);
> }
> </eucode>
{{{

> 
> Andy Katz
> B.S. Computer Science, 1978
> Rensselaer Polytechnic Institute (RPI)

I ran your code and get:

F:\eu\WIN32LIB\w32msgs.e:112 in procedure fShowError() 
attempt to divide by 0 
    pParams = "Draw function not found"
    pMode = 2
    lErrCode = 0
    lResponse = 1
    lStyle = 16
    s = "Draw function not found"
    lDispMsg = "Draw function not found\n\nWin32Lib v0.60.6 11-Jul-2004"
    lTitle = "Win32Lib AppWindow - Fatal Error"

... called from F:\eu\WIN32LIB\w32msgs.e:145 in procedure abortErr()  
    pParams = "Draw function not found"

... called from F:\euNFL06\test.exw:36 

Line 36 being this line:

abortErr(  "Draw function not found" )

What am I doing wrong?


Don Cole

new topic     » goto parent     » topic index » view message » categorize

5. Re: Why I need to use C for screen graphics

don cole wrote:
> 
> Andrew Katz wrote:
> > 
> > I would love to have my application be 100% Euphoria, since it claims to be
> > such a fast language. However, I have to do some work in C because Euphoria
> > is too slow. Euphoria is okay most of the time. But here is an example where
> > compiled C is 20 times faster. I wrote a test case to prove it.
> > Rensselaer Polytechnic Institute (RPI)

-- Code snipped ---
> 
> I ran your code and get:
> 
> F:\eu\WIN32LIB\w32msgs.e:112 in procedure fShowError() 
> attempt to divide by 0 
>     pParams = "Draw function not found"
>     pMode = 2
>     lErrCode = 0
>     lResponse = 1
>     lStyle = 16
>     s = "Draw function not found"
>     lDispMsg = "Draw function not found\n\nWin32Lib v0.60.6 11-Jul-2004"
>     lTitle = "Win32Lib AppWindow - Fatal Error"
> 
> ... called from F:\eu\WIN32LIB\w32msgs.e:145 in procedure abortErr()  
>     pParams = "Draw function not found"
> 
> ... called from F:\euNFL06\test.exw:36 
> 
> Line 36 being this line:
> 
> abortErr(  "Draw function not found" )
> 
> What am I doing wrong?
> 
> 
> Don Cole

Don:

You have to take my C code and use a C compiler (I use Watcom) to make a DLL
file. If you are not familiar with C, and really want to learn, contact me off
forum. But this test case is really a mute point, since an earlier reply
explained to me how to use Euphoria to get my speed improvement.

Andy Katz

B.S. Computer Science, 1978
Rensselaer Polytechnic Institute (RPI)

new topic     » goto parent     » topic index » view message » categorize

6. Re: Why I need to use C for screen graphics

Larry Miller wrote:
> 
> There are indeed cases where Euphoria is simply too slow. But this is not one
> of them. The performance bottleneck here is the Win32Lib function drawLine().
> This function is convenient to use but it is not fast. It calls getDC(),
> createPen(),
> and releaseDC() for every line drawn. I modified the RUNE_onClick() procedure
> as follows:
> 
> }}}
<eucode>
> procedure RUNE_onClick (integer self, integer event, sequence params)--params
> is ()
> -- run Euphoria drawing
> 
> integer x,y,PS_SOLID
> atom t0,hDC,hPen,void,hOldPen
> integer MsgBox
> t0 = time()
> PS_SOLID=0
> 
> setWindowBackColor( DRAWIN, backcolor )
> 
> set_rand(1500)
> hDC=getDC(DRAWIN)
> hPen=w32Func(xCreatePen,{PS_SOLID,1,0})
> hOldPen=w32Func(xSelectObject,{hDC,hPen})
> for i=1 to 100000 do
> 	x = rand(500)
> 	y = rand(500)
> 	void=w32Func(xMoveToEx,{hDC,x,y,NULL})
> 	void=w32Func(xLineTo,{hDC,x,y+2})
> end for
> void=w32Func(xSelectObject,{hDC,hOldPen})
> void=w32Func(xDeleteObject,{hPen})
> releaseDC(DRAWIN)
> 
> MsgBox = message_box(sprintf("Took %f time",{time()-t0}),"Test Euphoria", #0)
> 
> end procedure
> setHandler( RUNE, w32HClick, routine_id("RUNE_onClick"))
> 
> </eucode>
{{{

> 
> The speed improvement was dramatic. The original code executed in about 12
> seconds
> on my machine. The modified version took only .75 seconds.
> 
> Larry Miller

Thank you Larry. I did not know that the Windows functions were exposed in this
way with x in front of their names. I corrected your code - releaseDC should be
for DRAWIN.

I ran 3 options: My version with drawLine, my C version, and the Euphoria
version most similar to the C. My best times were 9.97, 0.51, 0.80 respectively.
So, Euphoria is still 60% slower. I now need to decide whether I should go for
maximum speed or the ease of programming in sticking to one language. I think for
now I will stick with Euphoria, and at some later date I will see where I can
increase speed.

By the way, after running the C version, the 1st Euphoria version speeds up to
3.95 seconds [in the same program run]. I have no idea why, but maybe someone can
use that information for understanding MS Windows or improving the Win32Lib.
There is no such speed up of the second Euphoria version.

I am going to attempt to use the Windows 2000/XP DC_PEN which lets you set the
color without having to create a new Pen object.

Andy Katz
B.S. Computer Science, 1978
Rensselaer Polytechnic Institute (RPI)

new topic     » goto parent     » topic index » view message » categorize

7. Re: Why I need to use C for screen graphics

Andrew Katz wrote:

> Don:
> 
> You have to take my C code and use a C compiler (I use Watcom) to make a DLL
> file. If you are not familiar with C, and really want to learn, contact me off
> forum. But this test case is really a mute point, since an earlier reply
> explained
> to me how to use Euphoria to get my speed improvement.
> 
> Andy Katz
> 
> B.S. Computer Science, 1978
> Rensselaer Polytechnic Institute (RPI)

Thank you for your response Andy,

I have download open Watcom and am working on the tutorial. I will let you know
privately if I need any help on it (I probably will). But for now I was just
interested in running the Euphoria part of your test.

Don Cole

new topic     » goto parent     » topic index » view message » categorize

8. Re: Why I need to use C for screen graphics

don cole wrote:
> 
> Andrew Katz wrote:
> 
> > Don:
> > 
> > You have to take my C code and use a C compiler (I use Watcom) to make a DLL
> > file. If you are not familiar with C, and really want to learn, contact me
> > off
> > forum. But this test case is really a mute point, since an earlier reply
> > explained
> > to me how to use Euphoria to get my speed improvement.
> > 
> > Andy Katz
> > 
> > B.S. Computer Science, 1978
> > Rensselaer Polytechnic Institute (RPI)
> 
> Thank you for your response Andy,
> 
> I have download open Watcom and am working on the tutorial. I will let you
> know
> privately if I need any help on it (I probably will). But for now I was just
> interested in running the Euphoria part of your test.

To see how that earlier reply effects things.

Don Cole

new topic     » goto parent     » topic index » view message » categorize

9. Re: Why I need to use C for screen graphics

I think you mean to say "Euphoria, using Win32Lib, is 60% slower."  I have
been away for a while, but I seem to remember that Win32Lib is coded for
simplicity, not speed.  You may have better luck using straight API calls.
Then again, I could be completely wrong...

new topic     » goto parent     » topic index » view message » categorize

10. Re: Why I need to use C for screen graphics

evanmars wrote:
> 
> I think you mean to say "Euphoria, using Win32Lib, is 60% slower."  I have
> been away for a while, but I seem to remember that Win32Lib is coded for
> simplicity, not speed.  You may have better luck using straight API calls.
> Then again, I could be completely wrong...

A previous reply gave that approach. I did not know about API calls in Euphoria.
It is exposed with x in front of the name. But even with these API calls,
Euphoria is still 60% slower. My original post was because I was using Win32Lib's
drawLine, and it was 2000% slower.

Note that for most applications this is not an issue. But my application needs
to write thousands of tiny little lines to make curved shapes.

Andy Katz
B.S. Computer Science, 1978
Rensselaer Polytechnic Institute (RPI)

new topic     » goto parent     » topic index » view message » categorize

11. Re: Why I need to use C for screen graphics

Andrew Katz wrote:
> still 60% slower.
I still read that as good, well actually, amazing. Bad point is Eu creates a
sequence to call a c_func, good point is it checks no of args, whether func/proc,
etc, and if it craps out on you most times it says straightaway what line it died
on, and if not, trace(3) does. C gives few clues.

> Note that for most applications this is not an issue. But my application
> needs to write thousands of tiny little lines to make curved shapes.
Agreed; there are times to resort to a crappy but fast language.
I write quite a bit in asm, btw, no matter my bitches over trace(), and I get
that OllyDbg is just about as good as it could be, I actually really like it, but
basically it still sucks in comparison.

Regards,
Pete

new topic     » goto parent     » topic index » view message » categorize

12. Re: Why I need to use C for screen graphics

Like an idiot I just wrote:
>good point is it checks no of args, whether func/proc,
sorry, that was a really duff point, comparing native to ffi.

Hangs head in shame,
Pete
PS I will stand and be counted as still amazed that Eu does that within the 60%,
btw.

new topic     » goto parent     » topic index » view message » categorize

13. Re: Why I need to use C for screen graphics

Pete Lomax wrote:
> 
> Andrew Katz wrote:
> > still 60% slower.
> I still read that as good, well actually, amazing. Bad point is Eu creates a
> sequence to call a c_func, good point is it checks no of args, whether
> func/proc,
> etc, and if it craps out on you most times it says straightaway what line it
> died on, and if not, trace(3) does. C gives few clues.
> 
> > Note that for most applications this is not an issue. But my application
> > needs to write thousands of tiny little lines to make curved shapes.
> Agreed; there are times to resort to a crappy but fast language.
> I write quite a bit in asm, btw, no matter my bitches over trace(), and I get
> that OllyDbg is just about as good as it could be, I actually really like it,
> but basically it still sucks in comparison.
> 
> Regards,
> Pete

Debugging assembly language. That is a scary thought. I like the Watcom C level
debugger. However, debugging a DLL is a challenge. I needed to make it an
application with just a function call, and plug in numbers for when it is called.

But since this is a Euphoria forum, we can say that Euphoria is great because of
the efforts of people here. And the community here is the best I have ever seen
for any language or tool set. This forum in particular is brilliant. Other sites
segregate the forum into groups. But here it is all in one place.

Andy Katz
B.S. Computer Science, 1978
Rensselaer Polytechnic Institute (RPI)

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu