2013-05-23 6 views
9

ich es mit diesem Code getestet:Warum ist Kolben url_for zu langsam

from gevent import wsgi, monkey; monkey.patch_all() 
from flask import Flask, url_for 

app = Flask(__name__) 

@app.route('/<int:n>') 
def index(n): 
    for i in xrange(n): 
     url = url_for('index', n=i) 
    return url 

wsgi.WSGIServer(('', 8000), app).serve_forever() 

Ergebnisse:

  • /1 Requests per second: 2721.94 [#/sec] (mean)
  • /10 Requests per second: 1080.16 [#/sec] (mean)
  • /100 Requests per second: 144.66 [#/sec] (mean)
+0

Was ist das eigentliche Problem, das Sie versuchen zu lösen? –

+0

Ich suche nach Möglichkeit, url_for Geschwindigkeit zu erhöhen, weil ich in der Nähe von 500 url_for auf einer Seite verwendet. Mit Test Kontext funktioniert es gut, nimmt dieser Code 0,06 sec: ctx = app.test_request_context() ctx.push() gestartet = time.time() für i in xrange (1000): url_for (‘ index ', n = i) print time.time() - gestartet – imbolc

+0

Wie haben Sie das Benchmarking durchgeführt (es scheint keinen Hinweis darauf zu geben, wie Sie die Anzahl der Anfragen pro Sekunde erhalten haben)? –

Antwort

2

der Tat ist es k Inda langsam.

Gute Nachrichten ist Zeit Komplexität ist linear, O(1).

Unten ist cProfile

Dump

Wenn ich ein Kolben Entwickler waren, ich aussehen würde, warum url_for beide Anrufe urljoin und urlsplit. Wenn ich den Werkzeugcode richtig verstehe, führt er eine Validierung der resultierenden URL durch.

  13726316 function calls (13526316 primitive calls) in 16.918 seconds 

    Ordered by: standard name 

    ncalls tottime percall cumtime percall filename:lineno(function) 
    400000 0.272 0.000 0.453 0.000 <string>:8(__new__) 
    100000 0.120 0.000 0.140 0.000 app.py:1484(inject_url_defaults) 
    200000 0.762 0.000 1.052 0.000 datastructures.py:316(__init__) 
    100000 0.132 0.000 0.395 0.000 globals.py:16(_lookup_object) 
    100000 0.913 0.000 16.996 0.000 helpers.py:250(url_for) 
    300000 0.527 0.000 0.846 0.000 local.py:156(top) 
    100000 0.136 0.000 0.645 0.000 local.py:289(_get_current_object) 
    100000 0.112 0.000 0.901 0.000 local.py:333(__getattr__) 
    300000 0.264 0.000 0.320 0.000 local.py:66(__getattr__) 
    200000 0.059 0.000 0.059 0.000 routing.py:1199(update) 
    200000 0.147 0.000 0.147 0.000 routing.py:1455(get_host) 
400000/200000 0.802 0.000 6.297 0.000 routing.py:1520(_partial_build) 
    200000 1.791 0.000 14.382 0.000 routing.py:1541(build) 
    400000 0.153 0.000 0.153 0.000 routing.py:1601(<genexpr>) 
    200000 1.830 0.000 5.181 0.000 routing.py:701(build) 
    200000 0.275 0.000 0.275 0.000 routing.py:743(suitable_for) 
    200000 0.256 0.000 0.256 0.000 routing.py:928(to_url) 
    400000 0.935 0.000 2.816 0.000 urlparse.py:128(urlparse) 
    400000 1.010 0.000 1.428 0.000 urlparse.py:159(urlsplit) 
    200000 0.175 0.000 0.274 0.000 urlparse.py:214(urlunparse) 
    200000 0.099 0.000 0.099 0.000 urlparse.py:224(urlunsplit) 
    200000 1.961 0.000 5.637 0.000 urlparse.py:242(urljoin) 
    5263 0.004 0.000 0.019 0.000 urlparse.py:62(clear_cache) 
    400000 0.483 0.000 0.783 0.000 urls.py:36(_quote) 
    400000 0.509 0.000 1.534 0.000 urls.py:369(url_quote) 
    100000 0.068 0.000 0.068 0.000 wrappers.py:85(blueprint) 
    505263 0.235 0.000 0.235 0.000 {built-in method __new__ of type object at 0x10d044248} 
    200000 0.101 0.000 0.169 0.000 {getattr} 
    100000 0.114 0.000 0.114 0.000 {hasattr} 
    2000000 0.642 0.000 0.642 0.000 {isinstance} 
    505263 0.073 0.000 0.073 0.000 {len} 
    200000 0.041 0.000 0.041 0.000 {method 'add' of 'set' objects} 
    600000 0.127 0.000 0.127 0.000 {method 'append' of 'list' objects} 
    5263 0.015 0.000 0.015 0.000 {method 'clear' of 'dict' objects} 
     1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} 
    5263 0.003 0.000 0.003 0.000 {method 'find' of 'str' objects} 
    100000 0.072 0.000 0.072 0.000 {method 'find' of 'unicode' objects} 
    700000 0.231 0.000 0.231 0.000 {method 'get' of 'dict' objects} 
    400000 0.105 0.000 0.105 0.000 {method 'iteritems' of 'dict' objects} 
    200000 0.116 0.000 0.116 0.000 {method 'join' of 'str' objects} 
    200000 0.157 0.000 0.157 0.000 {method 'join' of 'unicode' objects} 
    200000 0.134 0.000 0.134 0.000 {method 'lstrip' of 'unicode' objects} 
    300000 0.052 0.000 0.052 0.000 {method 'pop' of 'dict' objects} 
    200000 0.079 0.000 0.079 0.000 {method 'remove' of 'list' objects} 
    400000 0.249 0.000 0.249 0.000 {method 'rstrip' of 'str' objects} 
    200000 0.183 0.000 0.183 0.000 {method 'split' of 'str' objects} 
    400000 0.339 0.000 0.339 0.000 {method 'split' of 'unicode' objects} 
    300000 0.056 0.000 0.056 0.000 {thread.get_ident} 

Ich habe 2-3 praktische Lösungen für Sie:

  • Cache (am häufigsten) url_for Ergebnisse
  • Offload url_for Berechnung Client/js
  • hard url Generation

Wenn Sie RESTful API mit numerischen IDs haben, könnte die letzte Option wie folgt aussehen:

datum_url_template = url_for("datum", n=999) 
def url_for_datum(n): 
    return datum_url_template.replace("999", str(n)) 

foobar_url_template = url_for("foobar", n=777) 
def url_for_foobar(n): 
    return foobar_url_template.replace("777", str(n))