Page created:
Jun 17, 2009 (? ago)
Last modified ? ago
To main page | Opera Unite HowTo's

Opera Unite benchmark


Updates to original test

The original test flaw: CPU cores.

Since Opera uses only 1 proccess and therefore - only 1 core and PHP+Apache used 2 cores, I've set Apache CPU affinity to 1 core only (so that it uses same raw power) and PHP made only 771req/s. (As expected)

Opera Unite ~ 800 req/s
PHP on 1 core - 770 req/s
PHP+MySQL on same 1 core - 695 req/s.

Given the same "1 core" CPU: PHP/Apache is on par with Opera Unite (with less than 15 concurrent connections, which would be a heavy load - the Slashdot effect barely gives this server 1-2 concurrent connections)

The original test is flawed since all of those programs, except Opera use 2 cores. So results for PHP and nginx should be divided by 2. So, nginx wins only by 2.5 times, not 5.

This doesn't cancel the original results, though. Of course web server should use both cores, so on 2 core processors, PHP is still up to 2 times faster.

Note that this is test where only simple variables are used that definitely fit into memory. Unite isn't in same market as PHP/nginx. This test just shows that JavaScript can in fact be as effective as other server-side scripting languages.

Second test of Opera Unite today - up to 1050 req/s in some cases. (Uses 1 core), but I sense I shouldn't include these results into comparison, since some people already see me as a marketing agent for Opera Unite. (The source of this test is available below, BTW, test yourself)

Summary

Opera Unite can do up to impressive 800 requests per second on reasonably modern home hardware, even with dynamic content.

You can't DDOS a person via Opera Unite! (Unless you can sustain exactly 13 connections per second, no more, no less, but even then it's just takes 1 core and connection piling doesn't happen. (No overload)

Opera Unite uses very smart file I/O! Even if you save data to file each request (simplest, but stupidest way to do it) - it still can push out very impressive 744 requests/second! (It probably means that this data is saved to memory and dumped only sometimes, smart move!)

It seems like Opera uses 13 threads (seems like a soft limit, but unchangeable). 13 concurrent connections max out @ 810req/s, 1.23ms processing time.

For comparison:

PHP+Apache(+MySQL) is almost 2 times faster than peak Unite performance.

Compiled C++ web server (MadFish WebToolkit ) is only 6 times faster than Opera Unite, but that is compiled raw C++.

nginx (one of the fastest Web Servers available) is only 5 times faster than Opera Unite (clocked at 4900 req/s in raw C++) "Welcome to nginx" cycle (no I/O or scripting).

But if we were to compare simplicity of usage - those guys would seriously lose.

We can't really compare these technologies since they serve different (even though seemingly similar) ideas. Opera Unite isn't just "sites". And it isn't targeted to those who know what "nginx" is.

Static

Testing of serving almost static data:

config.xml
<widget>
  <widgetname>Static</widgetname>
  <feature name="http://xmlns.opera.com/fileio">
  </feature>
  <feature name="http://xmlns.opera.com/webserver">
    <param name="type" value="service"/>
    <param name="servicepath" value="static"/>
  </feature>
</widget>
index.html
<script>
window.onload = function () {
    webserver = opera.io.webserver
    if (webserver)    {
        webserver.addEventListener('_index', start_page, false);
    }
}
function start_page(r) {
    var o = r.connection.response;
    o.write('test');
    o.close();
}
</script>


Vertically more is better.


Less is better.

ab.exe -n {100,1000} -c [x axix]

The peak is at 13 concurrent connections at impressive 810 requests per second. (nginx "static" does ~3000requests/second).
Red graph = 100 total requests, blue graph = 1000 total requests.

1-2% Average CPU Utilization, peak at 14 req/s
44-45MB memory usage
     -c x      REQ/S     ms/req  avg ms/req  succes(total)
c =     1 :     92.8 |    10.78 |    10.78 |   100 ( 100)
c =     1 :     92.9 |    10.77 |    10.77 |  1000 (1000)
c =     2 :    188.2 |    10.63 |     5.31 |   100 ( 100)
c =     2 :    183.9 |    10.88 |     5.44 |  1000 (1000)
c =     3 :    266.7 |    11.25 |     3.75 |   100 ( 100)
c =     3 :    270.0 |    11.11 |     3.70 |  1000 (1000)
c =     4 :    336.8 |    11.88 |     2.97 |   100 ( 100)
c =     4 :    342.3 |    11.69 |     2.92 |  1000 (1000)
c =     5 :    426.7 |    11.72 |     2.34 |   100 ( 100)
c =     5 :    418.3 |    11.95 |     2.39 |  1000 (1000)
c =     6 :    492.3 |    12.19 |     2.03 |   100 ( 100)
c =     6 :    484.9 |    12.38 |     2.06 |  1000 (1000)
c =     7 :    533.3 |    13.13 |     1.88 |   100 ( 100)
c =     7 :    533.3 |    13.13 |     1.88 |  1000 (1000)
c =    10 :    711.1 |    14.06 |     1.41 |   100 ( 100)
c =    10 :    727.3 |    13.75 |     1.38 |  1000 (1000)
c =    11 :    711.1 |    15.47 |     1.41 |   100 ( 100)
c =    11 :    800.0 |    13.75 |     1.25 |  1000 (1000)
c =    12 :    640.0 |    18.75 |     1.56 |   100 ( 100)
c =    12 :    810.1 |    14.81 |     1.23 |  1000 (1000)
c =    13 :    800.0 |    16.25 |     1.25 |   100 ( 100)
c =    13 :    810.1 |    16.05 |     1.23 |  1000 (1000)
c =    14 :     97.0 |   144.38 |    10.31 |   100 ( 100)
c =    14 :    423.8 |    33.03 |     2.36 |  1000 (1000)
c =    15 :     36.0 |   417.19 |    27.81 |   100 ( 100)
c =    15 :    551.7 |    27.19 |     1.81 |  1000 (1000)
c =    16 :     30.8 |   520.00 |    32.50 |   100 ( 100)
c =    16 :     97.7 |   163.75 |    10.23 |  1000 (1000)
c =    17 :     32.2 |   528.59 |    31.09 |   100 ( 100)
c =    17 :    500.0 |    34.00 |     2.00 |  1000 (1000)
c =    18 :     28.1 |   641.25 |    35.63 |   100 ( 100)
c =    18 :     26.2 |   687.38 |    38.19 |  1000 (1000)
c =    19 :     27.8 |   682.81 |    35.94 |   100 ( 100)
c =    19 :     26.9 |   706.86 |    37.20 |  1000 (1000)
c =    20 :     26.2 |   762.50 |    38.13 |   100 ( 100)
c =    20 :     64.5 |   310.31 |    15.52 |  1000 (1000)
c =    50 :     41.0 |  1218.75 |    24.38 |   100 ( 100)
c =    50 :     34.1 |  1467.97 |    29.36 |  1000 (1000)
c =   100 :     33.5 |  2984.38 |    29.84 |   100 ( 100)
c =   100 :     31.3 |  3196.88 |    31.97 |  1000 (1000)
At 100 concurrent connections requests start to timeout.

It seems like Opera has something like 13 threads of execution?

Good news is that unless someone hits you at exactly 13 connections - no matter how big number is - CPU utilization is at a few percent.

Simple dynamic

The script keeps 1 variable, increments it and outputs (converting to string):
<script>
var c = 0;
window.onload = function () {
    webserver = opera.io.webserver
    if (webserver)    {
        webserver.addEventListener('_index', start_page, false);
    }
}
function start_page(r) {
    c++;
    var o = r.connection.response;
    o.write('test: '+c);
    o.close();
}
</script>




Red = 1000 total reqs, blue = 100 total reqs.

The performance doesn't drop compared to almost static content!

Persistence

No persistence was made to scripts, since I haven't found a way to do it better than saving data each request.

Adding stupid persistence:
<script src="file_wrap.js"></script>
<script>
var c = parseInt(safe_file_get('filename.txt', 0));

window.onload = function () {
    webserver = opera.io.webserver
    if (webserver)    {
        webserver.addEventListener('_index', start_page, false);
    }
}
function start_page(r) {
    c++;
    var o = r.connection.response;
    o.write('test: '+c);
    safe_file_put('filename.txt', c);
    o.close();
}
</script>
This is the stupidest way to do stuff and it seems Opera uses cache VERY REASONABLY. The performance should have dropped to about maybe 50 requests per second, but:



744 requests per second!
Kudos, Opera!

PHP comparison

PHP Version 5.2.4
Apache/2.2.4 (Win32)

Comparison to first (almost static) test:
<?= "test" ?>



Other servers/languages/frameworks on same system

PHP + MySQL

Well, since I don't want to kill my HDD I'm doind a test where PHP takes a value from simple MySQL table, increments a value and saves it back (using a set of functions that are typically used in web programming
<? 
mysql_pconnect('localhost','root','');
$rq=mysql_query('SELECT i FROM sqhash.p WHERE id=1');
$i=mysql_fetch_row($rq);
$i=$i[0];
$i=intval($i)+1;
mysql_query('UPDATE sqhash.p SET i="'.mysql_real_escape_string($i).
            '" WHERE id=1');
print "test".$i; 
?>
(Obviously you would need to setup 'sqhash.i' table with id=INT,PRIMARY KEY; i=INT.)



As disappointing it for me to be, but PHP+Apache beat Unite seriously.

Obviously in both tests CPU utilization was 100%.
(Twice the peak Unite usage and 10 times more than non-peak Unite usage)

Method

Testing was done as:
ab.exe -n ... -c ... http://mydevice.mylogin.operaunite.com:8840/static/
ab.exe is Apache Benchmark program (available in default Apache install).
8840 seems to be default port for Opera Unite server.

Edit hosts file:
127.0.0.1  mydevice.mylogin.operaunite.com

Clean C++ (compiled)

MadFish WebToolkit (under development)



nginx

Serving static "Welcome to nginx" content:



Testing system

Proc: Core2DUO 6420: 2 cores @2.13Ghz
RAM: 3GB

Source code for the test

You will need Python, and knowledge how it works, but if you're ready:
static.zip

Graphs by Google Chart API .

Slava V. [about me]


main page



Last updated


  1. Markuper (HTML templates)
  2. .ua
  3. Opera Unite HowTo's
  4. .us (files)
  5. Distribute Your Application
  6. 24/7 sites (permanent applications - idea) [stub]
  7. Issues
  8. HTTP Connections (AJAX/REST)
  9. Cookies
  10. file_wrap.js - File Wrapper
  11. Basic HowTo: Simple app (tutorial)
  12. Static images, client-side scripts
  13. Application Examples
  14. How to Debug Opera Unite apps
  15. Persistence & databases
  16. Opera Unite benchmark
  17. From PHP to Opera Unite
  18. Uniteness (Framework)
  19. Config.xml
  20. Key-value storage
  21. Widget Object
  22. Notifications (Growl'esque)
  23. Reset (debug)
  24. Cron example
  25. What I meant by CNAMEs
  26. Wish List
  27. Device Unavailable
  28. StopLorem (Opera Unite blogging)
  29. uniteness-0.11
  30. GET/POST data
  31. CRUD And Static (example)
  32. Opera object
  33. URLs
  34. Headers & Redirects
  35. Error Console
  36. JSON State (storing data)
  37. Security
  38. /storage/ (in fileio)
  39. Yusef library
  40. unite_info (a-la php_info)
  41. Javascript Imports
  42. onunload / _close
  43. fileio: Sandboxed Filesystem
  44. Request Hierarchy (like php_info)
  45. Intro: Web Apps with Opera Unite