Lösung
- Message => erstellen neue Instanzen so oft zum Pool nach Bedarf
- KeyFactory => um eine Shared-Instanz verwenden
- Secure => verwenden, um ein StackObjectPool
- Cipher => verwenden, um eine StackObjectPool
Frage
ich vor einer regelmäßige dilemna während Sicherheitscodierung Frameworks: „zu bündeln oder nicht zu bündeln“zum Pool oder nicht Java-Crypto Service Provider
Grundsätzlich ist diese Frage auf zwei „Gruppen“ unterteilt:
Gruppe 1:
SecureRandom
weil der Aufruf annextBytes(...)
ist synchronisiert und es könnte ein Engpass für eine WebApp/eine Multithread-App werdenGruppe 2: Crypto-Dienstanbieter wie
MessageDigest
,Signature
,Cipher
,KeyFactory
... (wegen der Kosten für diegetInstance()
?)
Was ist Ihre Meinung?
Was sind Gewohnheiten bei solchen Fragen?
bearbeiten 09/07/2013
Ich habe endlich Zeit @Qwerky Share
Klasse selbst zu testen, und ich finde das Ergebnis sehr ... überraschend.
Der Klasse fehlte meine Hauptsorge: Pools wie GenericObjectPool oder StackObjectPool.
Also habe ich die Klasse überarbeitet alle 4 Alternativen zu testen:
- Single Shared-Instanz mit Synchronisation gist
- neuen Instanzen innerhalb jeder Schleife (I im Fall interessiert mich nicht, wenn Sie ziehen der Digest Schaffung außerhalb der Schleife) gist
- GenericObjectPool: gist
- StackObjectPool: gist
Ich musste die Anzahl der Schleifen auf 100000 senken, da 1M zu viel Zeit mit Pools nahm.
Ich fügte auch eine Thread.yield()
am Ende jeder Schleife hinzu, um der Last eine schönere Form zu geben.
Ergebnisse (kumulative Laufzeit):
- Message
- neue Instanzen: 420 s
- Single Instance:
- StackObjectPool s 550: 800 s
- GenericObjectPool: 1900 s
- KeyFactory
- neue Instanzen: 400s
- Single Instance: 350 s
- StackObjectPool: 2900 s
- GenericObjectPool: 3500 s
- Secure
- StackObjectPool: 1600 s
- neue Instanzen : 2300 s
- GenericObjectPool: 2300S
- Single Instance: 2800 s
- Cipher
- StackObjectPool: 2800 s
- GenericObjectPool: 3500 s
- Single Instance: 5100 s
- neue Instanzen: 8000 s
Fazit
Für Message und KeyFactory, Pools sind perf Killer und sind sogar noch schlimmer als eine einzelne Instanz mit einem Synchronisations Engpass, während sie wirklich nützlich, wenn es um Secure und Cipher kommt
Die Wiederverwendung führt zu einem Kompromiss zwischen dem Aufwand für die teure Erstellung und dem synchronisierten Zugriff. Nur Sie können wählen und es hängt von Ihrem Nutzungsprofil ab. Beachten Sie, dass zwischen den beiden Gruppen kein Unterschied besteht. Sie müssen den Zugriff auf "MessageDigest" usw. synchronisieren, wenn Sie eine Instanz zwischen Threads teilen. – Qwerky
Natürlich @Qwerky jede Option erfordert Synchronisation zwischen Threads/Verwendungsblock. Die Frage ist vielmehr, wie gehen Sie mit diesen Klassen in Ihren Apps um? – Cerber
Das ist toll --- Ich wünschte, Informationen wie diese wären leichter für alle Arten von Klassen verfügbar. Wirklich, ich wünschte, es wäre im Standard-Javadoc. –