哪个更有效:嵌套谓词或选择父元素(通常遍历祖先)

时间:2016-11-01 09:02:14

标签: xpath

拥有这样的XML:

//bar[contains(text(), 'foobar')]/..

以下哪个XPath表达式更快/更有效地选择' foo'元素,包含某个' bar'元素:

//foo[bar[contains(text(), 'foobar')]]

private class CustomRenderer extends DefaultClusterRenderer<MyMarker>{

    private IconGenerator iconGenerator;
    private ImageView imageView;

    CustomRenderer() {
        super(ShopsMapActivity.this, map, clusterManager);
        iconGenerator = new IconGenerator(ShopsMapActivity.this);

        imageView = new ImageView(ShopsMapActivity.this.getApplicationContext());
        imageView.setLayoutParams(new ViewGroup.LayoutParams(PIN_SIZE, PIN_SIZE));
        int padding = Global.getXPercentOfWidth(1f);
        imageView.setPadding(padding, padding, padding, padding);
        iconGenerator.setContentView(imageView);
    }

    @Override
    protected void onBeforeClusterItemRendered(MyMarker item, MarkerOptions markerOptions) {
        if(item.hasLogo()) {
            // this part works perfectly
            loadAsync(imageView, item.getLogo());
            try {
                Bitmap icon = iconGenerator.makeIcon();
                markerOptions.icon(BitmapDescriptorFactory.fromBitmap(icon));
                icon.recycle();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }else {
         // this is the part that does not work. It should display a custom pin, but instead it displays a small empty white marker that should hold an image from Picasso. Problem is that there is no image for Picasso to download            
         markerOptions.icon(BitmapDescriptorFactory.fromBitmap(createDefaultIconBitmap()));
        }
    }

    private void loadAsync(final ImageView imageView, final String url) {
        Picasso.with(ShopsMapActivity.this)
                .load(url)
                .into(imageView);
    }

}

1 个答案:

答案 0 :(得分:1)

我认为你的问题的答案在很大程度上取决于所使用的特定XPath引擎的实现。

我使用xmllint(基于libxml)使用以下测试文档执行一些测量:

<root>
<foo><bar>      </bar></foo>
[... 99998 lines ommitted ...]
<foo><bar>      </bar></foo>
<foo><bar>   foobar   </bar></foo>
</root>

结果如下:

> time xmllint --repeat --xpath "//bar[contains(text(), 'foobar')]/.." test.xml > /dev/null 
real    0m34.984s
user    0m45.820s
sys     0m2.332s

> time xmllint --repeat --xpath "//foo[bar[contains(text(), 'foobar')]]" test.xml > /dev/null 
real    0m40.963s
user    0m40.660s
sys     0m0.260s

这似乎表明,在这种特殊情况下,第一个变体比第二个变体快得多。

更快的变体如下:

> time xmllint --repeat --xpath "//foo/bar[contains(text(), 'foobar')]/.." test.xml > /dev/null 
real    0m31.945s
user    0m31.692s
sys     0m0.212s

这似乎表明使用具有更多特定节点测试和避免谓词的位置路径似乎更好,但我不知道在一般情况下是否属实。