Simple Benchmark application

If anyone remembers GEMBench for the Atari ST, it basically drew windows and text and scrolled and justified text and created moire patterns and drew solid (filled) rectangles and such… as fast as possible. While those days of being amazed at how fast our computers were was fun, BeRometer was the closest thing we had to it in BeOS. But I don’t believe it was ever open-sourced or functions in Haiku nowadays. Ok, maybe the 32-bit version of Haiku (which mimics BeOS), but not the 64-bit version… or any other platform variant (I believe the only truly functional Haikus are x86 (32-bit), x86_64, and RiscV).

Which got me to thinking… what if we created a similar benchmark for today’s Haiku? So I got to digging, and I found this:

http://blog.leahhanson.us/post/haiku-first-gui-program.html

Took me a little while to figure out what was meant in what was said. I think Paladin has changed a bit since that blog was written, or maybe more descriptive text was left out, but I finally figured it out. However, come to find out, Paladin seems to now have this exact code already available within it. And, upon looking at it (and then running it), the code doesn’t exactly match the example in the blog, so I’m thinking Haiku’s code references have changed a bit, since then, as well.

But, anyhow…

That being said, how would we go about trying to replicate what GEMBench and/or BeRometer did? I’m not concerned with disk-oriented benchmarks, but graphical, memory, and CPU-bound benchmarks.

And, then, at some point, how would I go about making a Haiku (RiscV)-executable version?

2 Likes

I figure, as a first “benchmark”, we create an app, like Button Press, that, when you click on [Run], it opens and closes a single window (of a set size), say 100 (or 500?) times, as fast as it can. It then shows how long that took in x.xx seconds.

Update: Well, I’m learning new things… apparently when you do a “BRect (x, x, x, x)”, the first two numbers represent the X/Y coordinates of the upper left corner of the window (where the window starts). But the latter two numbers are not resolution-related (i.e. the window’s size (resolution) from the starting point), but rather the specific coordinates on the screen beyond the starting coordinates.

I couldn’t figure out why BRect (100, 100, 300, 200) produced a window that looked fine, but BRect (500, 500, 300, 200) produced a mashed down window. Now I know. Yay, me. :rofl:

Now, I’m going to try and figure out how to spawn another window, when you click [Click Me] (instead of just counting clicks). Any help? :grin:

The 4 values for BPoint are the xy of the left-top corner, and the xy of the bottom right corner of the window. That’s why they are named ‘left’, 'top, ‘right’ and ‘bottom’.

Instead of the code that count clicks, insert code that creates a new window:

BWindow* window = new BWindow(...);
window->Show();

You need to replace the “…” with the parameters for that window. You will need to provide at least a title and a BRect so the app_server knows how to name it and where to put it. You also need a window type (for example B_DOCUMENT_WINDOW will be a typical window with a tab and a resize knob) and flags (you can set them to 0).

Complete documentation for this is here: The Haiku Book: BWindow Class Reference

1 Like

In looking at the source code (“MainWindow.cpp”) from the Paladin app, this appears to be the area I’d focus on, correct?


void
MainWindow::MessageReceived(BMessage *msg)
{
// The way that BMessages are identified is by the public property ‘what’.
switch (msg->what)
{
// If the message was the one sent to the window by the button
case M_BUTTON_CLICKED:
{
fCount++;

		BString labelString("Clicks: ");
		
		// This adds the value of fCount to the end of labelString. More on this later.
		labelString << fCount;
		
		// Set the window's title to the new string we've made
		SetTitle(labelString.String());
		break;
	}

Knowing the general area I need to be in, helps identify the specific area I need to change. But do I change this whole block of code or do I just change a small section of it? I know that curly braces open and close areas of code, so I made the best guess I could that this entire section was independant (as it were) from the rest.

Yes, that seems to be the right part of the code.

You keep the things you still need to do:

void
MainWindow::MessageReceived(BMessage *msg)
{
// The way that BMessages are identified is by the public property ‘what’.
switch (msg->what)
{
    // If the message was the one sent to the window by the button
    case M_BUTTON_CLICKED:
    {
        // Here is the code that is run when the button is clicked
        // Insert the code to create a new window here
	    break;
    }
    // Here there are probably more cases for other messages that can be received
}

FWIW

Porting this would be ideal, it does everything you want and gives performance comparisons that make it useful to seeing how efficient haiku is relative to other OS designs. I didn’t read it all but a latency test would be helpful as well

I’m, personally, trying to learn a little about programming (what little I can comprehend at 55), while trying to create something that would qualify as a type of “benchmark”. Porting applications, unless the compiler can do all the work, would definitely be vastly beyond my pay grade. :grin:

Unfortunately, I got a ‘D’ in “Programming Logic” (when I took it at a local Community College in the early 2000’s) and so when I figured, “Oh, just copy and paste the previous code that draws a window”… I got a nasty set of error messages, and I’m trying to figure out what I’ve done wrong. My best guess, is “MainWindow” is NOT an instruction or command or whatever, but a user-choosable “label” (which means it can be anything… could have been called “BlargWindow” or whatever). Thus, I’m thinking you cannot call “MainWindow” more than once (without proper procedure). So, I’m assuming I have to name the spawned window something like “SecondWindow”?

This is what I created:


// Here is the code that is run when the button is clicked
    // Insert the code to create a new window here

enum
{
M_BUTTON_CLICKED = ‘btcl’
};

MainWindow::MainWindow(void)
: BWindow(BRect(300,300,500,400),“ClickMe”,B_TITLED_WINDOW, B_ASYNCHRONOUS_CONTROLS |
B_QUIT_ON_WINDOW_CLOSE),

Tried doing that (changing the name of the spawned window), aaaaand… seems it hasn’t been declared! I look to the top of the file and there is MainWindow.h! So, I suppose I need to create a SecondWindow.h file. But, if each spawned window has to have it’s own name and .h (header) file, that ends up getting ridiculous! 100’s of new names and .h files? Surely not! So, this is not going in the direction I thought it would. I’m pretty sure a loop is involved here, but I haven’t a clue as how to implement it. Should coding this be as simple as I imagined or far more complicated than I imagined? :man_shrugging:

You should give DarkWyrm´s tutorials a read ( they are linked in the documention part of the site ) . The basic structure and programming tips are well explained there

2 Likes

Yeah, I tried that. Didn’t work out so well. Big, hard fail. :grin: I can grasp some things and can’t grasp others. Desire does not equal ability, unfortunately.

@Luposian : You don´t necessarily have to use C++ to write apps for Haiku. Yab has bindings to the Haiku API as well and is probably easier to learn, being a BASIC dialect. And we have the newly created python bindings.

3 Likes

Here is just a simple empty window open, in YAB:

#!yab

doc Place a description of your
doc program here.
doc
doc Author, date, license

// set DEBUG = 1 to print out all messages on the console
DEBUG = 0

OpenWindow()

// Main Message Loop
dim msg$(1)
while(not leavingLoop)
nCommands = token(message$, msg$(), “|”)

for everyCommand = 1 to nCommands
	if(DEBUG and msg$(everyCommand)<>"") print msg$(everyCommand)

	switch(msg$(everyCommand))
		case "_QuitRequested"
		case "MainWindow:_QuitRequested"
			leavingLoop = true
			break
		default
			
	end switch

next everyCommand

wend

CloseWindow()

end

// Setup the main window here
sub OpenWindow()
window open 100,100 to 600,500, “MainWindow”, “Main Window”
return
end sub

// Close down the main window
sub CloseWindow()
window close “MainWindow”
return
end sub

Here is a simple Empty Window done in Paladin:

#include “MainWindow.h”

#include <Application.h>

MainWindow::MainWindow(void)
: BWindow(BRect(100,100,500,400),“Main Window”,B_TITLED_WINDOW, B_ASYNCHRONOUS_CONTROLS)
{
}

void
MainWindow::MessageReceived(BMessage *msg)
{
switch (msg->what)
{
default:
{
BWindow::MessageReceived(msg);
break;
}
}
}

bool
MainWindow::QuitRequested(void)
{
be_app->PostMessage(B_QUIT_REQUESTED);
return true;
}

Apart from the added “complication” of header (.h) files, the mainwindow.cpp file looks a lot simpler and easier to understand.

Of course, I still haven’t a clue how to make the program open and close a single window multiple times (automatically), while keeping track of how much time it took to do so. I’m thinking “QuitRequested” is the part where it responds to the user clicking on the close box. But how do you automate that, so it closes the window without you having to click on the close box? Then reopens the next one and so on… say 10 times or any number of times desired. I know there must be a loop involved and a way to reuse the same window name assignment.

Update: Learning… please stand by for progress. :grin:

I found this: Smashwords – Programming with yab

Ok, I found that this example (from the book) produces the EXACT same result, in a much easier to comprehend format:

#!yab
#This program is a better Hello World
//we can make comments
REM in different ways

//open a window
window open 100,100 to 600,500, “HelloWorldWindow”, “Example Program”

//make a view on the window
//the window itself is a kind of view, but DRAW SET does not work well on it
view 0,0 to 300,50, “HelloWorldView”, “HelloWorldWindow”

//draw the text
draw text 5, 40, “Hello, World!”, “HelloWorldView”

//start an infinite loop that can only be broken if the
//user closes the program
while(instr(message$, “Quit”) =0)
print “checking for message from Haiku …” //this shows the processes
wend
print “exiting program” //delete this when you understand it
exit


So, it’s obvious how to draw a window and even draw text on the window. And I know that the “while/wend” loop is what keeps the window there, until I click on the close box. But how do I display and then close and then display again, the same window x# of times, all by itself? Not to mention keeping track of how much time it took, and display the results.

I think I’ve gotten the previous example to open and close the window, but it happens so instantaneously, I can’t even see it happen! If you can’t even see the window appear, how do you even know it WAS there at all? Obviously, computers and OS’s today operate so fast, they can display something on screen instantly. But… you have to be able to see the window (even for a fraction of a second) before it’s closed, to even know it was displayed at all.

#!yab
while(1)
window open 100,100 to 600,500, “HelloWorldWindow”, “Example Program”
view 0,0 to 300,50, “HelloWorldView”, “HelloWorldWindow”
draw text 5, 40, “Hello, World!”, “HelloWorldView”
wend
exit

Well, I finally got the window to remain onscreen for a duration of time (sorry, CoolCoder613, but your code example keeps giving me syntax errors, not sure why):

#!yab
#This program is a better Hello World
//we can make comments
REM in different ways

while(a<100)
a=a+1
//open a window
window open 100,100 to 600,500, “HelloWorldWindow”, “Example Program”

//make a view on the window
//the window itself is a kind of view, but DRAW SET does not work well on it
view 0,0 to 300,50, “HelloWorldView”, “HelloWorldWindow”

//draw the text
draw text 5, 40, “Hello, World!”, “HelloWorldView”
print a
wend

exit


Now, to figure out how to repeat it x# of times, plus be able to time it.

my fault, I don’t know yab and I didn’t try it

For a code block, you use triple backticks
Like this:

```python
print(“Hello World!”)
```

Which becomes this:

print("Hello World!")