-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
BeanUtilでMapからBeanへ移送する際、ネストしたオブジェクト数が多い場合に処理が遅くなる #40
base: develop
Are you sure you want to change the base?
Conversation
|
||
PropertyExpression expression = new PropertyExpression(entry.getKey()); | ||
|
||
if (expression.isSimpleProperty() && expression.isNode()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
実装の話ですが、
まずexpression.isNode()
で分岐させて、その中で expression.isSimpleProperty()
かどうかを見たほうがすっきりするかなと
(261行目でも expression.isNode()
を参照しているので)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
全体的に構成を修正しました。
Object destObject; | ||
|
||
Class<?> propertyType = getPropertyType(bean.getClass(), propertyName); | ||
if (propertyType.isArray()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
この部分、 setArrayProperty()
と同様にメソッドに切り出した方が良いかなと思いました。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
こちらと上の方とで、同じような抽象度になるはずなので
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
全体的に構成を修正しました。
Array.set(propertyObject, propertyExpression.getListIndex(), destObject); | ||
} | ||
} | ||
} else if (List.class.isAssignableFrom(propertyType)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
こちらも同様に、setListProperty()
のようなメソッドになりそうですね
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
全体的に構成を修正しました。
for (Map.Entry<String, Map<String, Object>> entry : groupMap.entrySet()) { | ||
try { | ||
PropertyExpression nestedPropertyExpression = new PropertyExpression(entry.getKey()); | ||
setProperty(destObject, nestedPropertyExpression, entry.getValue(), copyOptions.reduce(nestedPropertyExpression.getRoot())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
439行目や417行目でConversionUtil.convert
を使っていますが、こちらでは使わなくて大丈夫でしょうか。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
既存の処理と同様にしています
} | ||
} catch (BeansException bex) { | ||
LOGGER.logDebug( | ||
"An error occurred while writing to the property :" + entry.getKey()); | ||
} | ||
} | ||
|
||
for (Map.Entry<String, Map<String, Object>> entry : groupedMap.entrySet()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
この部分、setProperty
でも同じような処理が出てきたと思いますが、まとめるのは難しいでしょうか?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
これはほぼ同じことを思います。
Mapの組み方は2種類、その後のループの内容が若干異なるのが差分のようなので、集約できそうに見えます。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
全体的に構成を修正しました。
@@ -857,43 +959,100 @@ static Map<String, Object> getReducedMap(String rootProperty, Map<String, ?> map | |||
} else if (expression.isListOrArray()) { | |||
Class<?> propertyType = getPropertyType(beanClass, expression.getListPropertyName()); | |||
if (propertyType.isArray()) { | |||
setArrayPropertyToMap(beanClass, expression, propertyMap, map, copyOptions); | |||
if (expression.isNode()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ここも、 expression.isNode()
の判定は外側で実施するのが良い気がします。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
全体的に構成を修正しました。
Map<String, Object> nodeMap = new HashMap<>(); | ||
Map<String, Object> nestedMap = new HashMap<>(); | ||
|
||
for(Map.Entry<String, ?> entry : map.entrySet()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
処理自体の話ではないですが、時々for(Map.Entry
のように空白が抜けたりしているので、修正箇所についてはフォーマッタをかけておいてください。
List<Map<String,Object>> separatedList = getSeparatedlist(map); | ||
|
||
for (int i = 0; i< 2; i++) { | ||
boolean isNode = i == 0; | ||
Map<String, Object> srcMap = separatedList.get(i); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
第三者から見ると「iが0だとどうしてノードなのか?」と不思議に思います。
引数のmap
をそのまま使うのではなく、getSeparatedlist
を必要とする理由は以降の処理で不要なループを増やさないためですよね?
メソッド名はgetSeparatedlist
ではなくgroupByNodeType
などにしてはどうでしょうか。
また返すのをList
ではなくMap
にして、Map
のキーで意味を識別させた方がよいような気がします。
どうでしょうか?
if (srcMap.isEmpty()) { | ||
continue; | ||
} | ||
if (expression.isSimpleProperty() && isNode) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
この箇所ですが、呼び出される経路によってはisNode
とexpression.isNode
が異なる結果になることがありますか?
for (Map.Entry<String, ?> mapEntry : map.entrySet()) { | ||
PropertyExpression keyAbsoluteExpression = expression.sibling(mapEntry.getKey()); | ||
PropertyExpression restExpression = keyAbsoluteExpression.rest(); | ||
groupMap.computeIfAbsent(restExpression.getParentKey() + "." + restExpression.getRoot(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
restExpression.getParentKey() + "." + restExpression.getRoot()
というパターンが頻出しますが、PropertyExpression
のメソッドにしてはどうでしょうか?
PropertyExpression#getAbsoluteRoot
などでよい気がします。
別コメントで書いたように、集約されるのならこのままでもよいかもですが。
* | ||
* @return リーフ要素のPropertyExpression | ||
*/ | ||
PropertyExpression leaf() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
このメソッド、使用箇所がないように見えますが意図的に残されていますか?
* @param propertyName プロパティ名 | ||
* @return 同一親をもつPropertyExpression | ||
*/ | ||
PropertyExpression sibling(String propertyName) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
このメソッド、使用箇所がないように見えますが意図的に残されていますか?
return parentKey; | ||
} | ||
|
||
String getAbsoluteRawKey() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
このメソッド、使用箇所がないように見えますが意図的に残されていますか?
LOGGER.logDebug( | ||
"An error occurred while writing to the property :" + nestedExpression.getAbsoluteRawKey()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
テストケースに、ここでの例外ハンドリング時にnestedExpression.getAbsoluteRawKey()
の結果が期待通りか確認するテストが必要ではないでしょうか?
いくつかのメソッドの引数に出てくる 既存のメソッドで、単一の値を設定するものは |
この修正の発端は、タイトルに書いてあるとおり「BeanUtilでMapからBeanへ移送する際、ネストしたオブジェクト数が多い場合に処理が遅くなる」なので、その対応結果が必要です。 目安として10,000件程度での修正前後の性能比較が上がっていたと思いますが、その結果を概要に追記しておいてください。 |
不具合内容
修正内容
テスト