question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Performance problems

See original GitHub issue

Hi!

I want to get know NATS + asyncio-nats-client RPS (request-response case). The test scenario is simple: server.py

import asyncio

import uvloop

from nats.aio.client import Client


async def main(loop):
    client = Client()
    await client.connect(io_loop=loop)
    print('connected')

    async def handler(msg):
        await client.publish(msg.reply, b'pong')

    await client.subscribe('test', queue='workers', cb=handler)
    print('subscribed')


if __name__ == '__main__':
    loop = uvloop.new_event_loop()
    asyncio.set_event_loop(loop)

    loop.run_until_complete(main(loop))
    print('start listening')
    loop.run_forever()
    loop.close()

client.py

import asyncio
import sys

import uvloop
from nats.aio.client import Client


async def main(loop):
    futures = [
        asyncio.ensure_future(client.timed_request('test', b'ping', 1))
        for i in range(int(sys.argv[1]))
    ]

    await asyncio.wait_for(asyncio.gather(*futures), 1.0)


if __name__ == '__main__':
    loop = uvloop.new_event_loop()
    asyncio.set_event_loop(loop)

    client = Client()
    loop.run_until_complete(client.connect(io_loop=loop))
    print('connected')

    loop.run_until_complete(main(loop))

How to run:

$ gnatsd
$ python3.6 server.py
$ python3.6 client.py 1000

I cant’ get more than 1000 requests/responses in 1 second on my MacBook Pro (2.3 GHz Intel Core i5). Maybe I do something wrong or it’s library limitations?

Thanks

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:12 (8 by maintainers)

github_iconTop GitHub Comments

2reactions
wallyqscommented, Apr 4, 2018

Thanks everyone for the feedback in this issue. In the next release v0.7.0 the inbox generation will be around twice as fast (although think implementation at https://github.com/nats-io/asyncio-nats/blob/master/nats/aio/nuid.py could be further optimized).

    print('NUID based inboxes x 100,000 times:\n%ss' % timeit.timeit(
        stmt='inbox = INBOX_PREFIX[:]; inbox.extend(nuid.next())',
        setup='from nats.aio.nuid import NUID; INBOX_PREFIX = bytearray(b"_INBOX."); nuid = NUID();',
        number=100000,
    ))

    print('Old style inboxes x 100,000 times:\n%ss' % timeit.timeit(
        stmt='new_inbox()',
        setup='from nats.aio.utils import new_inbox',
        number=100000,
    ))

Results:

NUID based inboxes x 100,000 times:
0.738977312023053s
Old style inboxes x 100,000 times:
1.3899898040108383s
```

Also with the internal changes to the request/response implementation (https://github.com/nats-io/asyncio-nats/pull/59) and using uvloop getting much results in the latency test:

```
# Before:

$ python3.6 benchmark/latency_perf.py 
Sending 10000 request/responses on [test]
#######################################
Test completed : 0.340 ms avg request/response latency

# After:

$ python3.6 benchmark/latency_perf.py 
Sending 10000 request/responses on [test]
#######################################
Test completed : 0.284 ms avg request/response latency
```
1reaction
Gr1Ncommented, Feb 14, 2018

About random, better to use SystemRandom, but move part of code to the top of module:

diff --git a/nats/aio/utils.py b/nats/aio/utils.py
index b289971..7aed392 100644
--- a/nats/aio/utils.py
+++ b/nats/aio/utils.py
@@ -2,6 +2,16 @@
 
 import random
 
+
+# Use the system PRNG if possible
+try:
+    random = random.SystemRandom()
+except NotImplementedError:
+    import warnings
+    warnings.warn('A secure pseudo-random number generator is not available '
+                  'on your system. Falling back to Mersenne Twister.')
+
+
 INBOX_PREFIX = "_INBOX."
 
 
@@ -9,7 +19,7 @@ def hex_rand(n):
     """
     Generates a hexadecimal string with `n` random bits.
     """
-    return "%x" % random.SystemRandom().getrandbits(n)
+    return "%x" % random.getrandbits(n)
 
 
 def new_inbox():

Read more comments on GitHub >

github_iconTop Results From Across the Web

Dealing with Performance Problems
Types of Performance Problems ; Quantity of work (untimely completion, limited production). Poor prioritizing, timing, scheduling; Lost time ; Quality of work ( ......
Read more >
What is a performance problem? - IBM
Generally, a performance problem is the result of some workload not getting the resources it needs to complete in time. Or the resource...
Read more >
68 Examples of Performance Problems - Simplicable Guide
Overreaction to Criticism, Passive Aggressive Behavior ; Poor Attention to Detail, Poor Budget Control ; Poor Listening Habits, Poor Work Quality.
Read more >
6 Common Employee Performance Problems & How to Solve ...
3. Your employees fail to finish tasks on time. Too Much Work ; 4. Your employees lack commitment. Performance Problems - Demotivation ;...
Read more >
7 Causes of Employee Performance Problems and How to ...
7 Causes of Employee Performance Problems and How to Deal With Them · 1. Don't have a reason to care · 2. Don't...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found