Glocke
Anmeldungsdatum: 1. März 2009
Beiträge: 880
Wohnort: Thüringen
|
Hi, derzeit arbeite ich an einem Browsergame (rundenbasiertes Rollenspiel) mit Python, bottle und elixir. Zur Kampfberechnung habe ich ein separates Skript, das zyklisch die Kampfaktionen einer Runde durchführt. Als Schnittstelle zur MySQL-Datenbank verwende ich elixir. Allerdings ist die Kampfberechnung zu langsam und ich habe überlegt, ob eine Neuimplementierung des Kampfsystems in einer anderen Sprache performanter wäre. Soweit ich das überblicke, ist C# um einiges schneller. Da ich im vergangenen Semester in meiner Uni ein C#-Seminar absolviert habe, kam mir die Idee, das Kampfsystem mittels C# und LINQ neu zu implementieren. Prinzipiell sollte es möglich sein, die Datenbankstruktur mit entsprechenden Klasse in C# zu modellieren und via LINQ auf den Datenbestand zuzugreifen. Ich hoffe, die Kampfberechnung dadurch merklich zu beschleunigen. Ist das realistisch? Danke fürs Lesen ☺ LG Glocke
|
diesch
Anmeldungsdatum: 18. Februar 2009
Beiträge: 5072
Wohnort: Brandenburg an der Havel
|
Das kommt darauf an, wie deine Kampfberechnung aussieht, und wo da die Zeit verbraten wird. Mit ORMs wie elixir hat man oft das Problem, dass man sehr viel mehr Datenbank-Zugriffe hat, als man beabsichtigt - und das bremst ein Programm natürlich schnell aus.
|
Glocke
(Themenstarter)
Anmeldungsdatum: 1. März 2009
Beiträge: 880
Wohnort: Thüringen
|
Also sollte ich vermutlich nochmal gründlich mit dem Profiler arbeiten, bevor ich mir die Mühe mache, oder? Die Klasse Combat hat eine Instanzmethode calculate , die die gesamte Kampfberechnung durchführt. Wie profile ich das am elegantesten? LG
|
noisefloor
Anmeldungsdatum: 6. Juni 2006
Beiträge: 29567
|
Hallo, Drei Punkte: Der Bottleneck ist auch IMHO die DB-Anfrage, nicht die Geschwindigkeit von Python an sich. Wenn du was schnelles brauchst bietet sich eine schnelle DB, die im Speicher läuft und asynchron im Hintergrund auf Platte schreibt - oder in eine relationale DB. Ein Kandidat dafür wäre Redis. Im deutschen Python-Forum wird immer wieder gesagt, dass Elexir Richtung "tot" läuft. Es gibt wohl noch Maintenance-Releases, aber keine Weiterentwicklung. Der deklarative Ansatz neuerer SQLalchemy Versionen hat Elexir wohl "überflüssig" gemacht. WENN du nichts desto trotz einen Teil der Spiellogik in einer anderen Sprache implementieren musst (willst?), dann schau' mal auf Lua. a) ist Lua "schnell", b) in der Spielentwicklung als Skript-Engine recht beliebt und c) gibt es AFAIK eine Python-Anbindung ☺
Gruß, noisefloor
|
Glocke
(Themenstarter)
Anmeldungsdatum: 1. März 2009
Beiträge: 880
Wohnort: Thüringen
|
noisefloor schrieb: Der Bottleneck ist auch IMHO die DB-Anfrage, nicht die Geschwindigkeit von Python an sich. Wenn du was schnelles brauchst bietet sich eine schnelle DB, die im Speicher läuft und asynchron im Hintergrund auf
Platte schreibt - oder in eine relationale DB.
Also könnte man sich einige Klassen zusammenbasteln (mit Locks bzw. Semaphoren für die Threadsicherheit), deren Instanzen die eigentlichen Daten erhalten, zur Laufzeit im Speicher liegen und zyklisch z.B. mit JSON in eine Datei dumpen (und beim Start des Servers laden)? (Will nur auf Nummer sicher gehen, dass ich das richtig verstanden habe ^^ ) LG Glocke
|
Lysander
Anmeldungsdatum: 30. Juli 2008
Beiträge: 2669
Wohnort: Hamburg
|
Glocke schrieb: (Will nur auf Nummer sicher gehen, dass ich das richtig verstanden habe ^^ )
Nein, Du sollst wenn eine fertige Lösung nehmen 😉 Die Jungs von Redis haben sicherlich da mehr Erfahrung bei Fallstricken als Du 😉 Ich frage mich nur, ob Deine Datenstrukturen evtl. schlecht designt sind. Musst Du denn *während* einer Kampfsimulation auf die DB zugreifen? Wenn ja, wieso? Ich kann mir anhand des Szenarios im Moment nicht wirklich vorstellen, wo da so große Daten herkommen sollten, dass man sie nicht im Speicher halten könnte...
|
Glocke
(Themenstarter)
Anmeldungsdatum: 1. März 2009
Beiträge: 880
Wohnort: Thüringen
|
Lysander schrieb: Nein, Du sollst wenn eine fertige Lösung nehmen 😉 Die Jungs von Redis haben sicherlich da mehr Erfahrung bei Fallstricken als Du 😉
Wenn ich was passendes finde, gern ☺ Mit Redis müsste ich Klasseninstanzen (Beispiel Charakter mit Lebensenergie, Ausrüstung usw.) beim Ablegen in der Redis-"Datenbank" serialisieren. Das bei jedem Lesen und Schreiben zu berücksichtigen .. klingt irgendwie nicht so elegant, finde ich. Lysander schrieb: Ich frage mich nur, ob Deine Datenstrukturen evtl. schlecht designt sind. Musst Du denn *während* einer Kampfsimulation auf die DB zugreifen? Wenn ja, wieso? Ich kann mir anhand des Szenarios im Moment nicht wirklich vorstellen, wo da so große Daten herkommen sollten, dass man sie nicht im Speicher halten könnte...
Hier mal der (kurze) Abriss der notwendigen Klassen: Combat
Referenz Angreifer-Gruppe Referenz Verteidiger-Gruppe Integer Timeout (wann Rundenberechnung ansteht)
Group
Character
u.A. Referenz auf Gruppe dazu Lebensenergie usw.
Während einer Kampfrunde gibt es zusätzlich Turn -Instanzen, die den gewählten Zug enthalten. Allein um die ausgewählten Aktionen zentral zu speichern, muss ich sie in der Datenbank ablegen. Die Charaktere werden nacheinander abgearbeitet, wobei jeweils z.B. die gespeicherte Aktion geladen und ausgewertet werden. Wo da große Datenmengen herkommen versteh ich nicht. Auf jedenfall dauern Kampfberechnungen zw 1.5 und 5 Sekunden, was für nen rundenbasiertes Spiel aus meiner Sicht schon grenzwertig ist. LG Glocke
|
Lysander
Anmeldungsdatum: 30. Juli 2008
Beiträge: 2669
Wohnort: Hamburg
|
Glocke schrieb: Wo da große Datenmengen herkommen versteh ich nicht. Auf jedenfall dauern Kampfberechnungen zw 1.5 und 5 Sekunden, was für nen rundenbasiertes Spiel aus meiner Sicht schon grenzwertig ist.
Naja, für ein *Runden basiertes* Spiel finde ich das eher weniger schlimm 😉 Dennoch müssen das ja ziemlich Datenmengen sein, wenn das so lange dauert! Läuft die DB denn auf demselben System? Also kann man Latenzen ausschließen? Ich denke das "ständige" Speichern von Sachen muss doch einfach nicht sein; man kann da sicherlich mehr auf einmal abarbeiten, ohne ständig "comitten" zu müssen... Aber zunächst solltest Du mal versuchen heraus zu finden, *wo* die Zeit herkommt. Ich kann nicht glauben, dass es da keine heftigen Schleifen oder *wirklich viele* IO-Operationen gibt...
|
Glocke
(Themenstarter)
Anmeldungsdatum: 1. März 2009
Beiträge: 880
Wohnort: Thüringen
|
Lysander schrieb: Naja, für ein *Runden basiertes* Spiel finde ich das eher weniger schlimm 😉
Naja werden es mehr Spieler dauert es dann insgesamt länger wenn zur gleichen Zeit mehrere Kämpfe berechnet werden müssen. Lysander schrieb: Dennoch müssen das ja ziemlich Datenmengen sein, wenn das so lange dauert! Läuft die DB denn auf demselben System? Also kann man Latenzen ausschließen?
Der zugehörige mysql-server läuft auf dem gleichen System. Lysander schrieb: Ich denke das "ständige" Speichern von Sachen muss doch einfach nicht sein; man kann da sicherlich mehr auf einmal abarbeiten, ohne ständig "comitten" zu müssen...
Naja ich verwende explizit session.commit nach der Berechnung eines Kampfes - zwischendrin nicht, um eben nicht ständig zu comitten. Lysander schrieb: Aber zunächst solltest Du mal versuchen heraus zu finden, *wo* die Zeit herkommt. Ich kann nicht glauben, dass es da keine heftigen Schleifen oder *wirklich viele* IO-Operationen gibt...
Naja es gibt eine große Schleife (für den Durchlauf der am Kampf beteiligten Spieler) und dann tiefergehend 2 bis 3 geschachtelte if -Verzweigungen (unterschiedliche Aktionen auswerten, Manakosten berücksichtigen, usw.) Ich kann es mir auch nicht so recht erklären. Ich werde mal versuchen den Profiler drüberzujagen.
|
noisefloor
Anmeldungsdatum: 6. Juni 2006
Beiträge: 29567
|
Hallo,
(und beim Start des Servers laden)? (Will nur auf Nummer sicher gehen, dass ich das richtig verstanden habe ^^ )
So ähnlich. Redis beherrscht asynchrones Speichern ootb automatisch - und hochgradig konfigurierbar! Hier im Wiki ist das ziemlich kurz beschrieben, in der kommenden Ausgabe von FreiesMagazin ist - wahrscheinlich - ein ziemlich umfangreicher Artikel zu Redis. Wenn du unbedingt einen ORM brauchst: Redisco ist ein ORM für Redis. Kenne ich aber auch nur vom Namen, habe ich noch nie genutzt. Ansonsten kennt Redis einen Datentyp namens "Hash" der im Prinzip einem Python-Dict entspricht. Übrigens behaupte ich _nicht_ das Redis die Wunderwaffe gegen deine Probleme ist ☺ Lysander hat ja schon ein paar andere, wichtige Punkte angesprochen. Gruß, noisefloor
|
Glocke
(Themenstarter)
Anmeldungsdatum: 1. März 2009
Beiträge: 880
Wohnort: Thüringen
|
Also ich hab mal combat.calculate() geprofiled: 233158 function calls (223064 primitive calls) in 4.868 CPU seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
80 0.001 0.000 0.009 0.000 <string>:1(<lambda>)
1 0.000 0.000 4.873 4.873 <string>:1(<module>)
3 0.000 0.000 0.439 0.146 <string>:1(__init__)
47 0.000 0.000 0.000 0.000 __init__.py:1310(getEffectiveLevel)
47 0.001 0.000 0.001 0.000 __init__.py:1324(isEnabledFor)
24 0.001 0.000 0.001 0.000 attributes.py:1029(_create_instance_state)
1048 0.012 0.000 0.012 0.000 attributes.py:1130(get_impl)
21 0.001 0.000 0.002 0.000 attributes.py:1139(new_instance)
3 0.000 0.000 0.000 0.000 attributes.py:1152(_new_state_if_none)
195 0.004 0.000 0.383 0.002 attributes.py:121(operate)
611 0.009 0.000 0.015 0.000 attributes.py:1319(__new__)
465 0.004 0.000 0.004 0.000 attributes.py:1322(__nonzero__)
119 0.002 0.000 0.002 0.000 attributes.py:1325(empty)
15 0.000 0.000 0.000 0.000 attributes.py:1336(sum)
164 0.006 0.000 0.010 0.000 attributes.py:1360(as_state)
447 0.016 0.000 0.036 0.000 attributes.py:1373(from_attribute)
317 0.006 0.000 0.058 0.000 attributes.py:1435(get_state_history)
32 0.001 0.000 0.006 0.000 attributes.py:152(__set__)
1463 0.033 0.000 0.376 0.000 attributes.py:159(__get__)
195 0.004 0.000 0.007 0.000 attributes.py:1757(manager_of_class)
6 0.000 0.000 0.000 0.000 attributes.py:321(sethasparent)
71 0.001 0.000 0.004 0.000 attributes.py:349(_get_callable)
24 0.000 0.000 0.000 0.000 attributes.py:357(initialize)
1619/1568 0.018 0.000 0.348 0.000 attributes.py:363(get)
242 0.005 0.000 0.007 0.000 attributes.py:405(get_committed_value)
47 0.002 0.000 0.006 0.000 attributes.py:416(set_committed_value)
316 0.007 0.000 0.034 0.000 attributes.py:446(get_history)
32 0.001 0.000 0.002 0.000 attributes.py:450(set)
158 0.003 0.000 0.015 0.000 attributes.py:574(get_history)
12 0.000 0.000 0.003 0.000 attributes.py:584(set)
12 0.001 0.000 0.001 0.000 attributes.py:612(fire_replace_event)
21 0.000 0.000 0.001 0.000 attributes.py:917(run)
216 0.007 0.000 2.182 0.010 base.py:1170(execute)
202 0.003 0.000 0.005 0.000 base.py:1184(get_select_precolumns)
216 0.007 0.000 0.013 0.000 base.py:1200(__distill_params)
80 0.001 0.000 0.001 0.000 base.py:1211(limit_clause)
3 0.000 0.000 0.004 0.001 base.py:1234(visit_update)
216 0.020 0.000 2.176 0.010 base.py:1249(_execute_clauseelement)
216 0.015 0.000 0.704 0.003 base.py:1292(__execute_context)
216 0.008 0.000 0.207 0.001 base.py:1375(__create_execution_context)
216 0.007 0.000 0.236 0.001 base.py:1388(_cursor_execute)
88 0.001 0.000 0.001 0.000 base.py:1978(__init__)
538 0.006 0.000 0.010 0.000 base.py:2004(__getitem__)
854 0.014 0.000 0.020 0.000 base.py:2049(__contains__)
202 0.174 0.001 0.414 0.002 base.py:2101(__init__)
2002 0.016 0.000 0.016 0.000 base.py:2114(<genexpr>)
854 0.007 0.000 0.007 0.000 base.py:2192(_has_key)
216 0.006 0.000 0.439 0.002 base.py:2251(__init__)
216 0.007 0.000 0.433 0.002 base.py:2261(_init_metadata)
11 0.000 0.000 0.001 0.000 base.py:2275(rowcount)
216 0.006 0.000 0.012 0.000 base.py:2312(_cursor_description)
216 0.002 0.000 0.006 0.000 base.py:2317(_autoclose)
216 0.005 0.000 0.034 0.000 base.py:2338(close)
23 0.001 0.000 0.001 0.000 base.py:236(__init__)
3 0.000 0.000 0.000 0.000 base.py:2374(inserted_primary_key)
8 0.000 0.000 0.000 0.000 base.py:2398(last_updated_params)
3 0.000 0.000 0.000 0.000 base.py:2407(last_inserted_params)
23 0.001 0.000 0.003 0.000 base.py:242(__init__)
11 0.000 0.000 0.000 0.000 base.py:2425(postfetch_cols)
11 0.000 0.000 0.000 0.000 base.py:2433(prefetch_cols)
202 0.007 0.000 0.021 0.000 base.py:2458(_fetchall_impl)
202 0.004 0.000 0.004 0.000 base.py:2473(process_rows)
202 0.007 0.000 0.064 0.000 base.py:2489(fetchall)
23 0.001 0.000 0.003 0.000 base.py:396(__init__)
1 0.000 0.000 0.000 0.000 base.py:415(bind_processor)
207 0.003 0.000 0.003 0.000 base.py:683(__init__)
207 0.004 0.000 1.190 0.006 base.py:699(compile)
4724/207 0.086 0.000 1.185 0.006 base.py:714(process)
216 0.002 0.000 0.002 0.000 base.py:717(__str__)
14 0.000 0.000 0.001 0.000 base.py:861(_clone)
14 0.000 0.000 0.002 0.000 base.py:869(execution_options)
448 0.004 0.000 0.004 0.000 base.py:891(dialect)
216 0.002 0.000 0.002 0.000 base.py:910(connection)
3 0.000 0.000 0.085 0.028 character.py:1010(life_leech)
3 0.000 0.000 0.043 0.014 character.py:1030(mana_leech)
18 0.001 0.000 0.525 0.029 character.py:1078(_turn)
33 0.001 0.000 1.025 0.031 character.py:1084(_combat)
9 0.001 0.000 0.592 0.066 character.py:1092(_opponent)
9 0.000 0.000 1.020 0.113 character.py:1101(_enemies)
3 0.000 0.000 0.250 0.083 character.py:1104(victorious)
22 0.001 0.000 1.052 0.048 character.py:1366(_characters)
33 0.003 0.000 1.017 0.031 character.py:1379(_combat)
3 0.000 0.000 0.041 0.014 character.py:150(__init__)
1 0.001 0.001 4.872 4.872 character.py:1666(calculate)
14 0.000 0.000 0.002 0.000 character.py:1836(opponent)
2 0.000 0.000 0.000 0.000 character.py:184(melee_skills)
5 0.000 0.000 0.246 0.049 character.py:1844(victorious)
3 0.000 0.000 0.429 0.143 character.py:1872(__init__)
1 0.000 0.000 0.000 0.000 character.py:191(ranged_skills)
3 0.002 0.001 2.643 0.881 character.py:1927(attack)
3 0.001 0.000 1.460 0.487 character.py:2358(AI)
90 0.006 0.000 1.561 0.017 character.py:266(__init__)
90 0.002 0.000 0.002 0.000 character.py:270(__iter__)
6 0.000 0.000 0.393 0.066 character.py:537(set_life)
3 0.000 0.000 0.185 0.062 character.py:551(set_mana)
32 0.001 0.000 0.002 0.000 character.py:558(<lambda>)
3 0.000 0.000 0.000 0.000 character.py:559(<lambda>)
9 0.001 0.000 0.233 0.026 character.py:578(get_name)
9 0.000 0.000 0.233 0.026 character.py:597(__unicode__)
76 0.001 0.000 0.001 0.000 character.py:616(current)
90 0.002 0.000 1.564 0.017 character.py:626(_effects)
3 0.000 0.000 0.041 0.014 character.py:635(_skills)
13 0.003 0.000 0.190 0.015 character.py:656(_strength)
10 0.002 0.000 0.130 0.013 character.py:675(_dexterity)
16 0.003 0.000 0.219 0.014 character.py:694(_wisdom)
6 0.001 0.000 0.392 0.065 character.py:717(_max_life)
3 0.001 0.000 0.185 0.062 character.py:743(_max_mana)
24 0.001 0.000 0.003 0.000 character.py:769(_level)
12 0.003 0.000 0.334 0.028 character.py:777(_weapon_damage)
12 0.003 0.000 0.339 0.028 character.py:840(_defense)
3 0.001 0.000 0.303 0.101 character.py:888(_avoidance)
3 0.001 0.000 0.088 0.029 character.py:916(_accuracy)
4 0.000 0.000 0.000 0.000 codecs.py:928(getencoder)
179 0.003 0.000 0.004 0.000 codecs.py:938(getdecoder)
1 0.000 0.000 0.001 0.001 compiler.py:1063(visit_delete)
94 0.002 0.000 0.005 0.000 compiler.py:1510(quote_identifier)
162 0.005 0.000 0.008 0.000 compiler.py:1519(_requires_quotes)
1800 0.015 0.000 0.015 0.000 compiler.py:153(__init__)
6056 0.057 0.000 0.071 0.000 compiler.py:1535(quote)
1800 0.057 0.000 0.101 0.000 compiler.py:1556(format_label)
5 0.000 0.000 0.000 0.000 compiler.py:1568(format_table)
1800 0.015 0.000 0.015 0.000 compiler.py:157(quote)
9 0.000 0.000 0.000 0.000 compiler.py:1578(format_column)
207 0.015 0.000 0.024 0.000 compiler.py:194(__init__)
216 0.010 0.000 0.052 0.000 compiler.py:257(construct_params)
14 0.000 0.000 0.009 0.001 compiler.py:305(visit_grouping)
1800 0.129 0.000 0.557 0.000 compiler.py:308(visit_label)
2020 0.110 0.000 0.184 0.000 compiler.py:333(visit_column)
32/18 0.001 0.000 0.029 0.002 compiler.py:400(visit_clauselist)
87/50 0.001 0.000 0.026 0.001 compiler.py:406(<genexpr>)
220 0.006 0.000 0.150 0.001 compiler.py:477(visit_binary)
220 0.008 0.000 0.129 0.001 compiler.py:486(<lambda>)
220 0.009 0.000 0.144 0.001 compiler.py:528(_operator_dispatch)
229 0.007 0.000 0.070 0.000 compiler.py:538(visit_bindparam)
238 0.012 0.000 0.053 0.000 compiler.py:599(_truncate_bindparam)
2028 0.061 0.000 0.092 0.000 compiler.py:611(_truncated_identifier)
225 0.009 0.000 0.014 0.000 compiler.py:629(_process_anon)
238 0.007 0.000 0.011 0.000 compiler.py:635(bindparam_string)
1800 0.055 0.000 0.101 0.000 compiler.py:661(label_select_column)
202 0.098 0.000 1.166 0.006 compiler.py:690(visit_select)
202 0.006 0.000 0.010 0.000 compiler.py:818(visit_table)
1 0.000 0.000 0.002 0.002 compiler.py:842(visit_insert)
9 0.000 0.000 0.002 0.000 compiler.py:915(_create_crud_bind_param)
4 0.001 0.000 0.004 0.001 compiler.py:931(_get_colparams)
15 0.000 0.000 0.000 0.000 compiler.py:961(<genexpr>)
27 0.000 0.000 0.001 0.000 connections.py:179(string_literal)
216 0.005 0.000 0.019 0.000 connections.py:217(cursor)
216 0.004 0.000 0.013 0.000 connections.py:236(literal)
3 0.000 0.000 0.000 0.000 converters.py:173(Bool2Str)
222 0.003 0.000 0.003 0.000 converters.py:55(Thing2Str)
1 0.000 0.000 0.000 0.000 converters.py:67(Float2Str)
9 0.000 0.000 0.000 0.000 converters.py:70(None2NULL)
3 0.000 0.000 0.000 0.000 core.py:202(__init__)
3 0.000 0.000 0.000 0.000 core.py:212(__unicode__)
157 0.005 0.000 0.007 0.000 core.py:262(ceil)
15 0.000 0.000 0.000 0.000 core.py:269(floor)
30 0.001 0.000 0.006 0.000 core.py:279(randomize)
10 0.000 0.000 0.001 0.000 core.py:68(random_pick)
3 0.000 0.000 0.000 0.000 core.py:72(random_pop)
216 0.020 0.000 0.047 0.000 cursors.py:107(_do_get_result)
1080 0.009 0.000 0.009 0.000 cursors.py:124(_get_db)
216 0.025 0.000 0.223 0.001 cursors.py:129(execute)
216 0.009 0.000 0.152 0.001 cursors.py:273(_do_query)
216 0.004 0.000 0.010 0.000 cursors.py:282(_fetch_row)
216 0.005 0.000 0.013 0.000 cursors.py:309(_get_result)
216 0.005 0.000 0.173 0.001 cursors.py:311(_query)
216 0.005 0.000 0.015 0.000 cursors.py:316(_post_get_result)
418 0.011 0.000 0.017 0.000 cursors.py:338(fetchall)
216 0.013 0.000 0.014 0.000 cursors.py:40(__init__)
216 0.004 0.000 0.006 0.000 cursors.py:57(__del__)
432 0.006 0.000 0.026 0.000 cursors.py:62(close)
418 0.003 0.000 0.003 0.000 cursors.py:68(_check_executed)
216 0.007 0.000 0.007 0.000 cursors.py:72(_warning_check)
216 0.008 0.000 0.021 0.000 cursors.py:87(nextset)
65 0.001 0.000 0.009 0.000 default.py:215(type_descriptor)
216 0.004 0.000 0.227 0.001 default.py:298(do_execute)
216 0.033 0.000 0.199 0.001 default.py:316(__init__)
220 0.005 0.000 0.032 0.000 default.py:366(<genexpr>)
478 0.009 0.000 0.027 0.000 default.py:367(<genexpr>)
3 0.000 0.000 0.000 0.000 default.py:434(_is_explicit_returning)
3 0.000 0.000 0.000 0.000 default.py:439(_is_implicit_returning)
216 0.009 0.000 0.012 0.000 default.py:494(__convert_compiled_params)
216 0.007 0.000 0.055 0.000 default.py:533(create_cursor)
216 0.001 0.000 0.001 0.000 default.py:536(pre_exec)
216 0.001 0.000 0.001 0.000 default.py:539(post_exec)
3 0.000 0.000 0.000 0.000 default.py:542(get_lastrowid)
216 0.005 0.000 0.444 0.002 default.py:574(get_result_proxy)
3 0.000 0.000 0.001 0.000 default.py:587(post_insert)
3 0.000 0.000 0.000 0.000 default.py:611(last_inserted_params)
8 0.000 0.000 0.000 0.000 default.py:614(last_updated_params)
3 0.000 0.000 0.000 0.000 default.py:660(_exec_default)
3 0.000 0.000 0.000 0.000 default.py:674(get_insert_default)
11 0.000 0.000 0.001 0.000 default.py:686(__process_defaults)
280 0.006 0.000 0.050 0.000 dependency.py:223(prop_has_changes)
6 0.000 0.000 0.000 0.000 dependency.py:237(_verify_canload)
143 0.002 0.000 0.007 0.000 dependency.py:50(per_property_preprocessors)
51 0.001 0.000 0.002 0.000 dependency.py:546(per_property_dependencies)
51 0.009 0.000 0.023 0.000 dependency.py:60(per_property_flush_actions)
15 0.000 0.000 0.000 0.000 dependency.py:637(presort_deletes)
128 0.002 0.000 0.009 0.000 dependency.py:658(presort_saves)
51 0.000 0.000 0.000 0.000 dependency.py:677(process_deletes)
51 0.002 0.000 0.018 0.000 dependency.py:695(process_saves)
6 0.000 0.000 0.002 0.000 dependency.py:707(_synchronize)
89 0.001 0.000 0.004 0.000 dependency.py:735(per_property_preprocessors)
89 0.001 0.000 0.001 0.000 dependency.py:756(presort_saves)
178 0.002 0.000 0.023 0.000 dependency.py:762(prop_has_changes)
89 0.004 0.000 0.021 0.000 dependency.py:780(_key_switchers)
89 0.001 0.000 0.001 0.000 dependency.py:783(<lambda>)
89 0.002 0.000 0.014 0.000 dependency.py:819(_pks_changed)
3 0.000 0.000 0.005 0.002 entity.py:1003(__init__)
3 0.000 0.000 0.005 0.002 entity.py:1006(set)
3 0.000 0.000 0.005 0.002 entity.py:1094(delete)
3 0.000 0.000 0.439 0.146 entity.py:41(__init__)
3 0.000 0.000 0.440 0.147 entity.py:826(__call__)
3 0.000 0.000 0.488 0.163 events.py:179(attack)
6 0.000 0.000 0.615 0.103 events.py:18(get_color)
3 0.000 0.000 0.000 0.000 events.py:262(get_critical_or_graze)
3 0.000 0.000 0.364 0.121 events.py:278(lost_life_and_mana)
1800 0.040 0.000 0.077 0.000 expression.py:1003(_literal_as_column)
585 0.022 0.000 0.037 0.000 expression.py:1089(_clone)
585 0.017 0.000 0.073 0.000 expression.py:1155(_annotate)
780 0.005 0.000 0.005 0.000 expression.py:1224(_copy_internals)
202 0.008 0.000 0.346 0.002 expression.py:123(select)
390 0.003 0.000 0.003 0.000 expression.py:1233(get_children)
21 0.000 0.000 0.000 0.000 expression.py:1247(self_group)
207 0.008 0.000 1.227 0.006 expression.py:1303(compile)
207 0.005 0.000 0.029 0.000 expression.py:1352(_compiler)
390 0.003 0.000 0.003 0.000 expression.py:1404(_clone)
198 0.004 0.000 0.393 0.002 expression.py:1442(__eq__)
7 0.005 0.001 0.007 0.001 expression.py:1533(__compare)
3 0.000 0.000 0.006 0.002 expression.py:1603(operate)
4 0.000 0.000 0.005 0.001 expression.py:1611(in_)
4 0.001 0.000 0.005 0.001 expression.py:1614(_in_impl)
7 0.000 0.000 0.001 0.000 expression.py:1780(_check_literal)
1800 0.012 0.000 0.012 0.000 expression.py:1826(_select_iterable)
280 0.005 0.000 0.007 0.000 expression.py:1843(shares_lineage)
64 0.002 0.000 0.003 0.000 expression.py:1992(__contains__)
4 0.000 0.000 0.001 0.000 expression.py:1997(contains_column)
4 0.000 0.000 0.001 0.000 expression.py:2125(corresponding_column)
214 0.014 0.000 0.018 0.000 expression.py:2261(__init__)
195 0.004 0.000 0.016 0.000 expression.py:2323(_clone)
262 0.008 0.000 0.014 0.000 expression.py:2336(bind_processor)
1 0.000 0.000 0.000 0.000 expression.py:253(insert)
425 0.017 0.000 0.028 0.000 expression.py:2568(__init__)
4 0.000 0.000 0.000 0.000 expression.py:2581(type)
28/14 0.001 0.000 0.002 0.000 expression.py:2615(_from_objects)
4 0.000 0.000 0.001 0.000 expression.py:2619(self_group)
17 0.001 0.000 0.006 0.000 expression.py:2646(__init__)
7 0.000 0.000 0.002 0.000 expression.py:2899(__init__)
216 0.005 0.000 0.007 0.000 expression.py:2917(_from_objects)
585 0.016 0.000 0.145 0.000 expression.py:2921(_copy_internals)
390 0.003 0.000 0.003 0.000 expression.py:2925(get_children)
2 0.000 0.000 0.000 0.000 expression.py:294(update)
28 0.000 0.000 0.002 0.000 expression.py:2946(self_group)
4 0.000 0.000 0.000 0.000 expression.py:3219(__init__)
14 0.000 0.000 0.001 0.000 expression.py:3233(_from_objects)
8 0.000 0.000 0.000 0.000 expression.py:3237(__getattr__)
64 0.004 0.000 0.012 0.000 expression.py:3388(_label)
2016 0.018 0.000 0.018 0.000 expression.py:3423(_from_objects)
7 0.000 0.000 0.001 0.000 expression.py:3430(_bind_param)
1 0.000 0.000 0.000 0.000 expression.py:344(delete)
1 0.000 0.000 0.000 0.000 expression.py:3508(insert)
2 0.000 0.000 0.000 0.000 expression.py:3513(update)
1 0.000 0.000 0.000 0.000 expression.py:3519(delete)
202 0.002 0.000 0.002 0.000 expression.py:3524(_from_objects)
202 0.012 0.000 0.038 0.000 expression.py:3531(__init__)
212 0.004 0.000 0.011 0.000 expression.py:359(and_)
202 0.073 0.000 0.338 0.002 expression.py:3813(__init__)
202 0.011 0.000 0.049 0.000 expression.py:3879(_get_display_froms)
202 0.003 0.000 0.040 0.000 expression.py:3963(inner_columns)
404 0.010 0.000 0.021 0.000 expression.py:4229(bind)
3 0.000 0.000 0.000 0.000 expression.py:4259(_process_colparams)
3 0.000 0.000 0.000 0.000 expression.py:4331(__init__)
1 0.000 0.000 0.000 0.000 expression.py:4372(__init__)
2 0.000 0.000 0.000 0.000 expression.py:4420(__init__)
1 0.000 0.000 0.000 0.000 expression.py:4473(__init__)
207 0.007 0.000 0.027 0.000 expression.py:744(bindparam)
128 0.003 0.000 0.005 0.000 expression.py:934(_escape_for_generated)
202 0.025 0.000 0.036 0.000 expression.py:950(_select_iterables)
217 0.003 0.000 0.005 0.000 expression.py:969(_is_literal)
606 0.031 0.000 0.056 0.000 expression.py:973(_from_objects)
11 0.000 0.000 0.000 0.000 expression.py:982(_column_as_key)
456 0.010 0.000 0.021 0.000 expression.py:989(_literal_as_text)
4 0.000 0.000 0.000 0.000 expression.py:997(_clause_element_as_expr)
142 0.002 0.000 0.002 0.000 identity.py:111(contains_state)
17 0.000 0.000 0.000 0.000 identity.py:114(replace)
24 0.001 0.000 0.001 0.000 identity.py:125(add)
15 0.001 0.000 0.002 0.000 identity.py:139(remove)
3 0.000 0.000 0.000 0.000 identity.py:149(discard)
106 0.002 0.000 0.002 0.000 identity.py:154(get)
24 0.000 0.000 0.000 0.000 identity.py:34(_manage_incoming_state)
18 0.000 0.000 0.001 0.000 identity.py:42(_manage_removed_state)
20 0.001 0.000 0.001 0.000 identity.py:47(_dirty_states)
20 0.000 0.000 0.000 0.000 identity.py:48(<genexpr>)
202 0.004 0.000 0.005 0.000 identity.py:51(check_modified)
30 0.000 0.000 0.000 0.000 identity.py:97(__contains__)
616 0.004 0.000 0.004 0.000 interfaces.py:1016(setup_query)
42 0.001 0.000 0.001 0.000 interfaces.py:468(cascade_iterator)
354 0.002 0.000 0.002 0.000 interfaces.py:522(per_property_preprocessors)
3527 0.086 0.000 0.288 0.000 interfaces.py:670(_get_context_strategy)
242 0.002 0.000 0.002 0.000 interfaces.py:681(_get_strategy)
2416 0.082 0.000 0.323 0.000 interfaces.py:692(setup)
1111 0.034 0.000 0.169 0.000 interfaces.py:696(create_row_processor)
3527 0.119 0.000 0.173 0.000 interfaces.py:966(_reduce_path)
3 0.000 0.000 0.000 0.000 item.py:80(__unicode__)
3 0.000 0.000 0.000 0.000 locale.py:102(localeconv)
9 0.000 0.000 0.000 0.000 locale.py:116(_grouping_intervals)
3 0.000 0.000 0.001 0.000 locale.py:132(_group)
3 0.000 0.000 0.001 0.000 locale.py:179(format)
3 0.000 0.000 0.001 0.000 locale.py:192(_format)
47 0.001 0.000 0.002 0.000 log.py:56(<lambda>)
9 0.000 0.000 0.006 0.001 mapper.py:1002(_single_table_criterion)
11 0.000 0.000 0.000 0.000 mapper.py:1009(<genexpr>)
9 0.000 0.000 0.000 0.000 mapper.py:1014(_with_polymorphic_mappers)
18 0.000 0.000 0.000 0.000 mapper.py:1020(_with_polymorphic_selectable)
9 0.001 0.000 0.010 0.001 mapper.py:1045(_polymorphic_properties)
180 0.003 0.000 0.008 0.000 mapper.py:1050(_iterate_polymorphic_properties)
6 0.000 0.000 0.000 0.000 mapper.py:1182(_canload)
6 0.000 0.000 0.000 0.000 mapper.py:1189(isa)
48 0.000 0.000 0.000 0.000 mapper.py:1197(iterate_to_root)
4 0.000 0.000 0.000 0.000 mapper.py:1203(self_and_descendants)
6 0.000 0.000 0.000 0.000 mapper.py:1232(primary_mapper)
204 0.002 0.000 0.002 0.000 mapper.py:1238(primary_base_mapper)
38 0.001 0.000 0.002 0.000 mapper.py:1259(identity_key_from_primary_key)
20 0.001 0.000 0.005 0.000 mapper.py:1280(_identity_key_from_state)
20 0.001 0.000 0.004 0.000 mapper.py:1292(_primary_key_from_state)
67 0.001 0.000 0.006 0.000 mapper.py:1298(_get_state_attr_by_column)
12 0.000 0.000 0.001 0.000 mapper.py:1301(_set_state_attr_by_column)
242 0.014 0.000 0.037 0.000 mapper.py:1309(_get_committed_state_attr_by_column)
6 0.004 0.001 0.013 0.002 mapper.py:1385(cascade_iterator)
3 0.000 0.000 0.000 0.000 mapper.py:1422(_compiled_cache)
6 0.000 0.000 0.024 0.004 mapper.py:1426(_sorted_tables)
20 0.007 0.000 0.025 0.001 mapper.py:1439(_per_mapper_flush_actions)
14 0.000 0.000 0.008 0.001 mapper.py:1467(_memo)
47 0.017 0.000 0.193 0.004 mapper.py:1563(_save_obj)
11 0.000 0.000 0.002 0.000 mapper.py:1653(<lambda>)
2 0.000 0.000 0.007 0.003 mapper.py:1804(update_stmt)
17 0.000 0.000 0.000 0.000 mapper.py:1887(<genexpr>)
11 0.001 0.000 0.010 0.001 mapper.py:1911(_postfetch)
4 0.000 0.000 0.008 0.002 mapper.py:1947(_table_to_equated)
47 0.005 0.000 0.041 0.001 mapper.py:1964(_delete_obj)
3 0.000 0.000 0.001 0.000 mapper.py:1980(<lambda>)
1 0.000 0.000 0.001 0.001 mapper.py:2026(delete_stmt)
217 0.026 0.000 0.035 0.000 mapper.py:2082(_instance_processor)
88 0.004 0.000 0.007 0.000 mapper.py:2114(identity_key)
49 0.008 0.000 0.239 0.005 mapper.py:2121(populate_state)
115/88 0.009 0.000 0.275 0.003 mapper.py:2160(_instance)
37 0.022 0.001 0.203 0.005 mapper.py:2303(_populators)
202 0.002 0.000 0.002 0.000 mapper.py:2317(_configure_subclass_mapper)
32 0.001 0.000 0.002 0.000 mapper.py:2321(configure_subclass_mapper)
3 0.000 0.000 0.000 0.000 mapper.py:2383(_event_on_init)
94 0.002 0.000 0.008 0.000 mapper.py:2414(_sort_states)
743 0.006 0.000 0.006 0.000 mapper.py:759(compile)
17 0.001 0.000 0.001 0.000 mapper.py:892(_is_orphan)
47 0.001 0.000 0.001 0.000 mapper.py:905(get_property)
18 0.000 0.000 0.001 0.000 mapper.py:947(iterate_properties)
11 0.000 0.000 0.001 0.000 mysqldb.py:58(rowcount)
94 0.002 0.000 0.004 0.000 mysqldb.py:76(_escape_identifier)
32 0.001 0.000 0.001 0.000 operators.py:133(is_precedent)
216 0.007 0.000 0.046 0.000 pool.py:422(cursor)
216 0.009 0.000 0.019 0.000 pool.py:494(__init__)
216 0.004 0.000 0.029 0.000 pool.py:505(close)
648 0.010 0.000 0.010 0.000 pool.py:518(__setattr__)
432 0.007 0.000 0.011 0.000 pool.py:524(__getattr__)
179 0.003 0.000 0.008 0.000 processors.py:52(to_unicode_processor_factory)
58 0.001 0.000 0.004 0.000 processors.py:55(process)
47 0.000 0.000 0.000 0.000 processors.py:87(int_to_boolean)
67 0.002 0.000 0.005 0.000 properties.py:119(_getattr)
242 0.007 0.000 0.022 0.000 properties.py:122(_getcommitted)
12 0.000 0.000 0.001 0.000 properties.py:126(_setattr)
143 0.002 0.000 0.009 0.000 properties.py:1381(per_property_preprocessors)
8 0.000 0.000 0.000 0.000 properties.py:143(get_col_value)
195 0.008 0.000 0.375 0.002 properties.py:570(__eq__)
7 0.000 0.000 0.000 0.000 properties.py:718(property)
195 0.010 0.000 0.251 0.001 properties.py:744(_optimized_compare)
30 0.001 0.000 0.006 0.000 properties.py:827(cascade_iterator)
242 0.004 0.000 0.084 0.000 query.py:102(__init__)
242 0.013 0.000 0.079 0.000 query.py:107(_set_entities)
242 0.011 0.000 0.034 0.000 query.py:116(_setup_aliasizers)
80 0.015 0.000 1.525 0.019 query.py:1425(__getitem__)
80 0.001 0.000 0.001 0.000 query.py:1448(slice)
115 0.014 0.000 2.322 0.020 query.py:1486(all)
80 0.003 0.000 1.529 0.019 query.py:1520(first)
7 0.001 0.000 0.275 0.039 query.py:1541(one)
202 0.009 0.000 3.597 0.018 query.py:1599(__iter__)
202 0.008 0.000 2.218 0.011 query.py:1606(_execute_and_instances)
290 0.034 0.000 0.470 0.002 query.py:1658(instances)
202 0.004 0.000 0.016 0.000 query.py:1681(<lambda>)
18 0.001 0.000 0.279 0.015 query.py:1794(_get)
202 0.002 0.000 0.002 0.000 query.py:1879(_select_args)
47 0.000 0.000 0.000 0.000 query.py:224(_adapt_all_clauses)
202 0.027 0.000 0.789 0.004 query.py:2242(_compile_context)
216 0.002 0.000 0.002 0.000 query.py:236(_adapt_clause)
202 0.005 0.000 0.018 0.000 query.py:2401(_adjust_for_single_inheritance)
242 0.008 0.000 0.019 0.000 query.py:2427(__new__)
242 0.005 0.000 0.007 0.000 query.py:2445(__init__)
242 0.005 0.000 0.005 0.000 query.py:2452(setup_entity)
404 0.005 0.000 0.005 0.000 query.py:2499(_get_entity_clauses)
202 0.012 0.000 0.049 0.000 query.py:2518(row_processor)
202 0.043 0.000 0.379 0.002 query.py:2555(setup_context)
213 0.002 0.000 0.002 0.000 query.py:264(_entity_zero)
18 0.000 0.000 0.000 0.000 query.py:267(_mapper_zero)
202 0.011 0.000 0.014 0.000 query.py:2717(__init__)
404 0.005 0.000 0.007 0.000 query.py:274(_mapper_entities)
202 0.001 0.000 0.001 0.000 query.py:2741(<genexpr>)
202 0.007 0.000 0.010 0.000 query.py:2761(_new_runid)
195 0.005 0.000 0.008 0.000 query.py:283(_joinpoint_zero)
202 0.004 0.000 0.005 0.000 query.py:288(_mapper_zero_or_none)
7 0.000 0.000 0.000 0.000 query.py:323(_get_condition)
7 0.000 0.000 0.000 0.000 query.py:327(_no_criterion_condition)
275 0.002 0.000 0.002 0.000 query.py:351(_no_statement_condition)
195 0.002 0.000 0.002 0.000 query.py:359(_no_limit_offset)
7 0.000 0.000 0.000 0.000 query.py:387(_get_options)
329 0.008 0.000 0.013 0.000 query.py:401(_clone)
322 0.014 0.000 0.045 0.000 query.py:47(generate)
195 0.007 0.000 0.013 0.000 query.py:860(filter)
195 0.016 0.000 0.466 0.002 query.py:885(filter_by)
43 0.001 0.000 0.002 0.000 random.py:173(randrange)
1 0.000 0.000 0.000 0.000 schema.py:1288(is_callable)
1 0.000 0.000 0.000 0.000 schema.py:1292(is_clause_element)
61 0.000 0.000 0.000 0.000 schema.py:1335(_visit_name)
7 0.000 0.000 0.001 0.000 schema.py:1590(__iter__)
3 0.000 0.000 0.000 0.000 schema.py:1593(__len__)
390 0.003 0.000 0.003 0.000 schema.py:1949(bind)
1 0.000 0.000 0.000 0.000 schema.py:317(_autoincrement_column)
7 0.000 0.000 0.000 0.000 schema.py:331(primary_key)
390 0.007 0.000 0.011 0.000 schema.py:344(bind)
6 0.000 0.000 0.001 0.000 schema.py:410(get_children)
91 0.001 0.000 0.001 0.000 schema.py:67(get_children)
298 0.007 0.000 0.012 0.000 schema.py:925(get_children)
195 0.009 0.000 0.098 0.001 scoping.py:116(__get__)
3 0.000 0.000 0.009 0.003 scoping.py:131(do)
17 0.001 0.000 0.008 0.000 session.py:1013(_register_newly_persistent)
3 0.000 0.000 0.001 0.000 session.py:1040(_remove_newly_deleted)
3 0.000 0.000 0.009 0.003 session.py:1054(add)
3 0.000 0.000 0.009 0.003 session.py:1073(_save_or_update_state)
3 0.000 0.000 0.009 0.003 session.py:1077(_cascade_save_or_update)
3 0.000 0.000 0.005 0.002 session.py:1082(delete)
3 0.000 0.000 0.000 0.000 session.py:1234(_save_impl)
3 0.000 0.000 0.000 0.000 session.py:1265(_save_or_update_impl)
6 0.000 0.000 0.000 0.000 session.py:1282(_attach)
6 0.000 0.000 0.000 0.000 session.py:1302(__contains__)
154 0.003 0.000 0.005 0.000 session.py:1320(_contains_state)
202 0.005 0.000 0.577 0.003 session.py:1323(flush)
202 0.008 0.000 0.571 0.003 session.py:1363(_flush)
20 0.000 0.000 0.002 0.000 session.py:1506(_dirty_states)
3 0.000 0.000 0.004 0.001 session.py:1559(_cascade_state_iterator)
3 0.000 0.000 0.009 0.003 session.py:1567(_cascade_unknown_state_iterator)
3 0.000 0.000 0.000 0.000 session.py:1592(_state_for_unknown_persistence_instance)
3 0.000 0.000 0.000 0.000 session.py:1628(object_session)
56 0.001 0.000 0.002 0.000 session.py:1641(_state_session)
20 0.001 0.000 0.001 0.000 session.py:210(__init__)
524 0.008 0.000 0.012 0.000 session.py:229(_assert_is_active)
544 0.004 0.000 0.004 0.000 session.py:236(_assert_is_open)
20 0.000 0.000 0.000 0.000 session.py:240(_is_transaction_boundary)
94 0.004 0.000 0.033 0.000 session.py:244(connection)
20 0.001 0.000 0.002 0.000 session.py:249(_begin)
20 0.000 0.000 0.001 0.000 session.py:264(_take_snapshot)
390/296 0.008 0.000 0.017 0.000 session.py:300(_connection_for_bind)
20 0.001 0.000 0.001 0.000 session.py:339(_prepare_impl)
20 0.001 0.000 0.003 0.000 session.py:364(commit)
40 0.000 0.000 0.000 0.000 session.py:412(_deactivate)
20 0.000 0.000 0.000 0.000 session.py:415(close)
20 0.000 0.000 0.003 0.000 session.py:507(begin)
202 0.004 0.000 0.012 0.000 session.py:639(_connection_for_bind)
202 0.012 0.000 2.205 0.011 session.py:645(execute)
296 0.015 0.000 0.069 0.000 session.py:782(get_bind)
242 0.005 0.000 0.089 0.000 session.py:836(query)
202 0.004 0.000 0.580 0.003 session.py:841(_autoflush)
202 0.004 0.000 0.006 0.000 session.py:845(_finalize_loaded)
474 0.017 0.000 0.078 0.000 state.py:111(get_history)
574 0.010 0.000 0.017 0.000 state.py:114(get_impl)
21 0.000 0.000 0.001 0.000 state.py:141(_run_on_load)
243 0.006 0.000 0.009 0.000 state.py:195(reset)
24 0.000 0.000 0.000 0.000 state.py:27(__init__)
17 0.001 0.000 0.001 0.000 state.py:292(unmodified)
95 0.006 0.000 0.010 0.000 state.py:298(unloaded)
29 0.000 0.000 0.000 0.000 state.py:32(committed_state)
6 0.000 0.000 0.000 0.000 state.py:322(_instance_dict)
44 0.001 0.000 0.001 0.000 state.py:328(modified_event)
75 0.004 0.000 0.007 0.000 state.py:351(commit)
3 0.000 0.000 0.000 0.000 state.py:36(parents)
38 0.002 0.000 0.002 0.000 state.py:375(commit_all)
22 0.000 0.000 0.000 0.000 state.py:44(callables)
168 0.002 0.000 0.002 0.000 state.py:48(has_identity)
18 0.000 0.000 0.000 0.000 state.py:52(detach)
18 0.000 0.000 0.000 0.000 state.py:59(dispose)
18 0.001 0.000 0.003 0.000 state.py:63(_cleanup)
732 0.011 0.000 0.011 0.000 state.py:77(dict)
20 0.000 0.000 0.000 0.000 state.py:85(sort_key)
3 0.000 0.000 0.439 0.146 state.py:89(initialize_instance)
1800 0.030 0.000 0.042 0.000 strategies.py:100(setup_query)
854 0.020 0.000 0.041 0.000 strategies.py:120(create_row_processor)
406 0.007 0.000 0.015 0.000 strategies.py:128(new_execute)
195 0.011 0.000 0.239 0.001 strategies.py:406(lazy_clause)
195 0.002 0.000 0.002 0.000 strategies.py:434(visit_bindparam)
195 0.005 0.000 0.037 0.000 strategies.py:451(<lambda>)
59 0.002 0.000 0.003 0.000 strategies.py:484(_class_level_loader)
257 0.003 0.000 0.003 0.000 strategies.py:490(create_row_processor)
243 0.004 0.000 0.013 0.000 strategies.py:504(new_execute)
195 0.018 0.000 0.140 0.001 strategies.py:517(_create_lazy_clause)
585 0.008 0.000 0.034 0.000 strategies.py:534(col_to_bind)
390 0.004 0.000 0.004 0.000 strategies.py:557(<genexpr>)
47 0.000 0.000 0.000 0.000 strategies.py:566(__init__)
47 0.007 0.000 0.320 0.007 strategies.py:575(__call__)
6 0.000 0.000 0.002 0.000 sync.py:13(populate)
89 0.002 0.000 0.011 0.000 sync.py:67(source_modified)
129 0.022 0.000 0.029 0.000 topological.py:14(sort_as_subsets)
228 0.003 0.000 0.032 0.000 topological.py:36(sort)
20 0.007 0.000 0.012 0.001 topological.py:46(find_cycles)
2 0.000 0.000 0.000 0.000 types.py:105(_type_affinity)
23 0.000 0.000 0.000 0.000 types.py:1123(__init__)
23 0.001 0.000 0.004 0.000 types.py:1138(adapt)
166 0.001 0.000 0.001 0.000 types.py:1141(result_processor)
7 0.000 0.000 0.000 0.000 types.py:119(_coerce_compared_value)
65 0.000 0.000 0.000 0.000 types.py:163(_impl_dict)
17 0.000 0.000 0.000 0.000 types.py:1643(__init__)
2062 0.029 0.000 0.040 0.000 types.py:167(dialect_impl)
236 0.002 0.000 0.002 0.000 types.py:1672(result_processor)
234 0.002 0.000 0.002 0.000 types.py:180(bind_processor)
1183 0.008 0.000 0.008 0.000 types.py:192(result_processor)
24 0.001 0.000 0.001 0.000 types.py:596(to_instance)
65 0.003 0.000 0.008 0.000 types.py:605(adapt_type)
15 0.000 0.000 0.000 0.000 types.py:68(compare_values)
27 0.000 0.000 0.000 0.000 types.py:780(bind_processor)
4 0.000 0.000 0.000 0.000 types.py:799(process)
215 0.005 0.000 0.013 0.000 types.py:810(result_processor)
20 0.000 0.000 0.000 0.000 unitofwork.py:119(has_work)
6 0.000 0.000 0.000 0.000 unitofwork.py:123(is_deleted)
89 0.001 0.000 0.002 0.000 unitofwork.py:129(memo)
277 0.011 0.000 0.056 0.000 unitofwork.py:143(get_attribute_history)
232 0.005 0.000 0.007 0.000 unitofwork.py:170(register_preprocessor)
148 0.004 0.000 0.034 0.000 unitofwork.py:175(register_object)
20 0.000 0.000 0.001 0.000 unitofwork.py:198(_mapper_for_dep)
348 0.006 0.000 0.008 0.000 unitofwork.py:209(<lambda>)
114 0.002 0.000 0.002 0.000 unitofwork.py:220(states_for_mapper_hierarchy)
20 0.007 0.000 0.216 0.011 unitofwork.py:227(_generate_actions)
20 0.005 0.000 0.511 0.026 unitofwork.py:278(execute)
20 0.001 0.000 0.009 0.000 unitofwork.py:302(finalize_flush_changes)
515 0.010 0.000 0.013 0.000 unitofwork.py:318(_mappers)
1150 0.015 0.000 0.030 0.000 unitofwork.py:321(<genexpr>)
232 0.003 0.000 0.003 0.000 unitofwork.py:328(__init__)
464 0.040 0.000 0.196 0.000 unitofwork.py:334(execute)
346 0.005 0.000 0.007 0.000 unitofwork.py:370(__new__)
102 0.002 0.000 0.003 0.000 unitofwork.py:390(__init__)
102 0.003 0.000 0.021 0.000 unitofwork.py:396(execute)
147 0.003 0.000 0.006 0.000 unitofwork.py:417(_elements)
122 0.002 0.000 0.002 0.000 unitofwork.py:436(__init__)
47 0.002 0.000 0.195 0.004 unitofwork.py:440(execute)
122 0.001 0.000 0.001 0.000 unitofwork.py:459(__init__)
47 0.001 0.000 0.043 0.001 unitofwork.py:463(execute)
12 0.000 0.000 0.000 0.000 unitofwork.py:53(set)
20 0.001 0.000 0.001 0.000 unitofwork.py:73(__init__)
1857 0.028 0.000 0.054 0.000 utf_8.py:15(decode)
208 0.002 0.000 0.002 0.000 util.py:1018(__init__)
88 0.001 0.000 0.002 0.000 util.py:1024(add)
94 0.001 0.000 0.002 0.000 util.py:1027(__contains__)
30 0.000 0.000 0.000 0.000 util.py:12(visit_foreign_key)
413 0.026 0.000 0.046 0.000 util.py:1238(unique_list)
198 0.002 0.000 0.002 0.000 util.py:1333(__call__)
301/282 0.006 0.000 0.061 0.000 util.py:1495(__get__)
28 0.001 0.000 0.004 0.000 util.py:157(__new__)
28 0.000 0.000 0.000 0.000 util.py:162(__init__)
3 0.000 0.000 0.000 0.000 util.py:1647(__init__)
9 0.000 0.000 0.000 0.000 util.py:1651(__getitem__)
5 0.000 0.000 0.000 0.000 util.py:1666(__setitem__)
5 0.000 0.000 0.000 0.000 util.py:1675(_manage_size)
28 0.001 0.000 0.006 0.000 util.py:168(union)
893 0.010 0.000 0.015 0.000 util.py:205(to_list)
585 0.011 0.000 0.015 0.000 util.py:237(__new__)
585 0.016 0.000 0.040 0.000 util.py:253(__init__)
6 0.000 0.000 0.000 0.000 util.py:27(<genexpr>)
585/195 0.015 0.000 0.143 0.001 util.py:274(_compiler_dispatch)
780 0.011 0.000 0.017 0.000 util.py:292(__hash__)
195 0.003 0.000 0.109 0.001 util.py:309(_deep_annotate)
585/195 0.021 0.000 0.105 0.001 util.py:315(clone)
80 0.005 0.000 0.009 0.000 util.py:334(decode_slice)
195 0.004 0.000 0.113 0.001 util.py:382(_orm_annotate)
30 0.001 0.000 0.001 0.000 util.py:47(__contains__)
242 0.009 0.000 0.014 0.000 util.py:522(_entity_info)
195 0.005 0.000 0.012 0.000 util.py:557(_entity_descriptor)
296 0.004 0.000 0.007 0.000 util.py:586(_is_aliased_class)
136 0.001 0.000 0.001 0.000 util.py:589(_state_mapper)
195 0.006 0.000 0.014 0.000 util.py:607(class_mapper)
296 0.012 0.000 0.026 0.000 util.py:625(_class_to_mapper)
242 0.004 0.000 0.006 0.000 util.py:642(_is_mapped_class)
24 0.000 0.000 0.000 0.000 util.py:674(identity_equal)
6 0.000 0.000 0.023 0.004 util.py:7(sort_tables)
9 0.000 0.000 0.000 0.000 util.py:765(__len__)
25 0.000 0.000 0.002 0.000 util.py:768(__iter__)
523 0.005 0.000 0.005 0.000 util.py:79(__init__)
64 0.001 0.000 0.001 0.000 util.py:798(__contains__)
619 0.011 0.000 0.037 0.000 util.py:82(__missing__)
6 0.000 0.000 0.000 0.000 util.py:822(__init__)
51 0.001 0.000 0.001 0.000 util.py:861(__iter__)
106 0.005 0.000 0.005 0.000 util.py:864(values)
86 0.002 0.000 0.007 0.000 util.py:867(itervalues)
47 0.001 0.000 0.001 0.000 util.py:870(keys)
6 0.000 0.000 0.000 0.000 util.py:882(__setitem__)
404 0.009 0.000 0.024 0.000 util.py:909(__init__)
2420 0.032 0.000 0.035 0.000 util.py:915(add)
1301 0.020 0.000 0.030 0.000 util.py:941(__iter__)
606 0.028 0.000 0.064 0.000 util.py:949(update)
202 0.008 0.000 0.032 0.000 util.py:978(difference)
404 0.003 0.000 0.003 0.000 util.py:980(<genexpr>)
206 0.006 0.000 0.016 0.000 visitors.py:158(iterate)
6 0.004 0.001 0.021 0.004 visitors.py:186(traverse_using)
6 0.000 0.000 0.021 0.004 visitors.py:195(traverse)
195 0.027 0.000 0.088 0.000 visitors.py:205(cloned_traverse)
585 0.011 0.000 0.040 0.000 visitors.py:210(clone)
195 0.026 0.000 0.115 0.001 visitors.py:232(replacement_traverse)
585 0.016 0.000 0.066 0.000 visitors.py:238(clone)
4724/207 0.114 0.000 1.181 0.006 visitors.py:47(_compiler_dispatch)
6 0.000 0.000 0.000 0.000 weakref.py:245(remove)
6 0.000 0.000 0.000 0.000 weakref.py:261(__setitem__)
50 0.000 0.000 0.000 0.000 weakref.py:55(__getitem__)
183 0.002 0.000 0.002 0.000 {_codecs.lookup}
1857 0.026 0.000 0.026 0.000 {_codecs.utf_8_decode}
4 0.000 0.000 0.000 0.000 {_codecs.utf_8_encode}
3 0.000 0.000 0.000 0.000 {_locale.localeconv}
216 0.002 0.000 0.002 0.000 {_weakref.proxy}
1 0.000 0.000 0.000 0.000 {abs}
2611 0.024 0.000 0.024 0.000 {built-in method __new__ of type object at 0x8245fc0}
202 0.004 0.000 0.004 0.000 {built-in method describe}
202 0.007 0.000 0.007 0.000 {built-in method fetch_row}
202 0.002 0.000 0.002 0.000 {built-in method field_flags}
3 0.000 0.000 0.000 0.000 {built-in method group}
162 0.002 0.000 0.002 0.000 {built-in method match}
466 0.003 0.000 0.003 0.000 {callable}
5303 0.051 0.000 0.052 0.000 {getattr}
3939 0.048 0.000 0.048 0.000 {hasattr}
780 0.005 0.000 0.005 0.000 {hash}
390 0.003 0.000 0.003 0.000 {id}
17723 0.151 0.000 0.151 0.000 {isinstance}
38 0.000 0.000 0.000 0.000 {issubclass}
1914/1907 0.014 0.000 0.015 0.000 {iter}
7664/7661 0.051 0.000 0.051 0.000 {len}
157 0.001 0.000 0.001 0.000 {math.ceil}
1 0.000 0.000 0.000 0.000 {math.log}
217 0.002 0.000 0.002 0.000 {method 'acquire' of 'thread.lock' objects}
3218 0.021 0.000 0.021 0.000 {method 'add' of 'set' objects}
216 0.002 0.000 0.002 0.000 {method 'affected_rows' of '_mysql.connection' objects}
194 0.001 0.000 0.001 0.000 {method 'append' of 'collections.deque' objects}
11368 0.076 0.000 0.076 0.000 {method 'append' of 'list' objects}
216 0.002 0.000 0.002 0.000 {method 'character_set_name' of '_mysql.connection' objects}
2314 0.033 0.000 0.033 0.000 {method 'copy' of 'dict' objects}
208 0.002 0.000 0.002 0.000 {method 'copy' of 'set' objects}
1800 0.047 0.000 0.099 0.000 {method 'decode' of 'str' objects}
1491 0.012 0.000 0.012 0.000 {method 'difference' of 'set' objects}
103 0.001 0.000 0.001 0.000 {method 'difference_update' of 'set' objects}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
53 0.000 0.000 0.000 0.000 {method 'discard' of 'set' objects}
216 0.006 0.000 0.006 0.000 {method 'encode' of 'unicode' objects}
216 0.006 0.000 0.009 0.000 {method 'escape' of '_mysql.connection' objects}
7 0.000 0.000 0.000 0.000 {method 'extend' of 'collections.deque' objects}
7 0.000 0.000 0.000 0.000 {method 'extend' of 'list' objects}
10 0.001 0.000 0.234 0.023 {method 'format' of 'unicode' objects}
7228 0.054 0.000 0.054 0.000 {method 'get' of 'dict' objects}
195 0.002 0.000 0.002 0.000 {method 'get' of 'dictproxy' objects}
216 0.001 0.000 0.001 0.000 {method 'info' of '_mysql.connection' objects}
216 0.002 0.000 0.002 0.000 {method 'insert_id' of '_mysql.connection' objects}
904 0.007 0.000 0.007 0.000 {method 'intersection' of 'set' objects}
21 0.000 0.000 0.000 0.000 {method 'issuperset' of 'frozenset' objects}
202 0.001 0.000 0.001 0.000 {method 'items' of 'dict' objects}
690 0.005 0.000 0.005 0.000 {method 'iteritems' of 'dict' objects}
6 0.000 0.000 0.000 0.000 {method 'iterkeys' of 'dict' objects}
444/430 0.007 0.000 0.034 0.000 {method 'join' of 'str' objects}
216 0.001 0.000 0.001 0.000 {method 'keys' of 'dict' objects}
71 0.000 0.000 0.000 0.000 {method 'lower' of 'str' objects}
5491 0.044 0.000 0.044 0.000 {method 'lower' of 'unicode' objects}
216 0.002 0.000 0.002 0.000 {method 'next_result' of '_mysql.connection' objects}
2739 0.018 0.000 0.018 0.000 {method 'pop' of 'dict' objects}
1653 0.013 0.000 0.013 0.000 {method 'pop' of 'list' objects}
115 0.001 0.000 0.001 0.000 {method 'pop' of 'set' objects}
207 0.001 0.000 0.001 0.000 {method 'popleft' of 'collections.deque' objects}
216 0.094 0.000 0.094 0.000 {method 'query' of '_mysql.connection' objects}
48 0.000 0.000 0.000 0.000 {method 'random' of '_random.Random' objects}
217 0.002 0.000 0.002 0.000 {method 'release' of 'thread.lock' objects}
81 0.001 0.000 0.001 0.000 {method 'remove' of 'set' objects}
119 0.001 0.000 0.001 0.000 {method 'replace' of 'str' objects}
230 0.002 0.000 0.002 0.000 {method 'replace' of 'unicode' objects}
3 0.000 0.000 0.000 0.000 {method 'reverse' of 'list' objects}
2060 0.016 0.000 0.016 0.000 {method 'setdefault' of 'dict' objects}
225 0.003 0.000 0.003 0.000 {method 'split' of 'unicode' objects}
216 0.006 0.000 0.006 0.000 {method 'store_result' of '_mysql.connection' objects}
27 0.000 0.000 0.000 0.000 {method 'string_literal' of '_mysql.connection' objects}
129 0.001 0.000 0.001 0.000 {method 'union' of 'set' objects}
14 0.000 0.000 0.000 0.000 {method 'update' of 'dict' objects}
283 0.002 0.000 0.002 0.000 {method 'update' of 'set' objects}
484 0.003 0.000 0.003 0.000 {method 'values' of 'dict' objects}
216 0.002 0.000 0.002 0.000 {method 'warning_count' of '_mysql.connection' objects}
6 0.000 0.000 0.000 0.000 {min}
195 0.004 0.000 0.379 0.002 {operator.eq}
39 0.001 0.000 0.005 0.000 {setattr}
94 0.004 0.000 0.007 0.000 {sorted}
1 0.000 0.000 0.000 0.000 {time.localtime}
1 0.000 0.000 0.000 0.000 {time.mktime}
14 0.000 0.000 0.000 0.000 {time.time}
212 0.002 0.000 0.003 0.000 {zip} Zum Auswerten der Daten bin ich jetzt nicht mehr in der Lage ... *tot ins Bett fall* Gute Nacht,
LG Glocke
|
Glocke
(Themenstarter)
Anmeldungsdatum: 1. März 2009
Beiträge: 880
Wohnort: Thüringen
|
Hi, ich werde aus dem Log nicht schlau: die Werte von tottime (was für mich nach total time, also recht interessant klingt) ergeben kaum größere Zahlen.... Auffallend ist, dass mehr Bestandteile elixir verwendet werden, als von meinem eigenen Code. Unabhängig davon: Würde eine statische typisierung (cdef ) und Kompilieren mittels Cython da helfen? Ich habe mit 'ner Primzahlfunktion mal herum experimentiert: Jedesmal liegt die Berechnung der Primzahlen bis 1.000 zugrunde:
klassisches Python: ~0.4344s Cython ohne cdef : ~0.2958s Cython mit cdef : ~0.0358s
Sind die Werteunterschiede generell in der Größenordnung? LG Glocke
|
noisefloor
Anmeldungsdatum: 6. Juni 2006
Beiträge: 29567
|
Hallo, na ja, alles, was eine "größere" total time hat (relativ gesehen) sieht schon so aus, als käme es von Elexir. Dass du mehr Elexir-Operation drin hast als von dir initiiert ist IMHO ziemlich normal, da Elexir ja ziemlich "high level" ist und unter der Haube viel mehr abläuft - was vor die aber verborgen bleibt. Wie sieht eigentlich den Programmablauf auf? Wenn ich den Profiler richtig verstehe hast du wohl DB-Zugriffe bei der Kampfberechung? Besser wäre IMHO, wenn alle Daten, die für combat() benötigt werden dann auch wirklich im Speicher sind und im Speicher gehalten werden. Den Zugriff auf die DB kannst du ja zwischen den Runden erledigen, wenn die Nutzer ihr nächste Aktion im Browser zusammen klicken. In diesem Zusammenhang müsstest du vielleicht auch mal schauen, ob Elexir (bzw. SQLalchemy) nicht DB-Zugriffe puffert / sammelt und dann "irgendwann" ausführt - vielleicht auch dann, wenn du es gar nicht willst. Und noch ein letzter Punkt: Du erwähntest eine Spanne von 1.5 - 5 Sekunden. Ich gehe davon aus, dass du auf einem Desktop-System entwickelst? Dann solltest du natürlich bei so Zeitmessungen darauf achten, dass a) nichts anderes rechenintensives läuft und b) das System nicht swappt. Gruß, noisefloor
|
Glocke
(Themenstarter)
Anmeldungsdatum: 1. März 2009
Beiträge: 880
Wohnort: Thüringen
|
noisefloor schrieb: Wie sieht eigentlich den Programmablauf auf? Wenn ich den Profiler richtig verstehe hast du wohl DB-Zugriffe bei der Kampfberechung? Besser wäre IMHO, wenn alle Daten, die für combat() benötigt werden dann auch wirklich im Speicher sind und im Speicher gehalten werden. Den Zugriff auf die DB kannst du ja zwischen den Runden erledigen, wenn die Nutzer ihr nächste Aktion im Browser zusammen klicken.
Naja ich habe div. von Entity abgeleitete Objekte. Wenn ich die Properties / Field -Instanzen dieser Objekte lese oder schreibe (also z.B. Lebensenergie verändere oder den Stärke-Wert auslese), dann wird dies ja (wenn wir das mit dem puffern erstmal außen vor lassen) jedesmal eine Datenbankanfrage erzeugen. Ich müsste - wenn ich alle Werte am Anfang holen will - sämtliche Daten aus der Datenbank lesen, in separaten (nicht mit der Datenbank in Verbindung stehenden) Objekten abspeichern und dann damit arbeiten. Dann hätte ich mir glaube die Verwendung eines ORM sparen können, befürchte ich 😕 noisefloor schrieb: In diesem Zusammenhang müsstest du vielleicht auch mal schauen, ob Elexir (bzw. SQLalchemy) nicht DB-Zugriffe puffert / sammelt und dann "irgendwann" ausführt - vielleicht auch dann, wenn du es gar nicht willst.
Soweit ich weiß, gibt es dafür ein session -Objekt. Mit session.commit() kann ich die Änderungen "durchführen" (quasi die Transaktion abschließen) und mit session.rollback() analog die Transaktion abbrechen. Daher gehe ich davon aus, dass Elixir in gewisser Weise die Anfragen erst sammelt und beim commit durchführt. noisefloor schrieb: Und noch ein letzter Punkt: Du erwähntest eine Spanne von 1.5 - 5 Sekunden. Ich gehe davon aus, dass du auf einem Desktop-System entwickelst? Dann solltest du natürlich bei so Zeitmessungen darauf achten, dass a) nichts anderes rechenintensives läuft und b) das System nicht swappt.
Ja, Desktop-System (genauer: Netbook). Viel läuft parallel nicht: chromium-browser , dropbox , pidgin und geany sowie 'nen Terminal.
Die Kampfberechnung scheint vom Spielerlevel (damit größere Zahlen für Schaden usw.) und natürlich von der Anzahl der am Kampf beteiligten Chars (1on1 oder 4on4 macht ja durchaus einen Unterschied) abhängig zu sein. LG Glocke
|
noisefloor
Anmeldungsdatum: 6. Juni 2006
Beiträge: 29567
|
Hallo,
Dann hätte ich mir glaube die Verwendung eines ORM sparen können, befürchte ich
Nicht unbedingt. Das kannst den "Komfort" des ORM doch auch weiter nutzen. Rohes SQL ist ja auch nicht immer unbedingt das komfortabelste. ☺
Die Kampfberechnung scheint vom Spielerlevel (damit größere Zahlen für Schaden usw.)
Echt? Klingt irgendwie komisch... IMHO sollte die Berechnung doch unabhängig davon sein...? Gruß, noisefloor
|