Improve lang speed by reducing environment copying

Currently, for every bound rule for every key in lang, the `idmap` is copied and specialized to match the required execution environment for that rule. E.g. `text: self.name + root.text` requires `self` and `root` in the `idmap` execution environment to be specialized to this line. All this `idmap` copying requires tons of memory and reduces perfs.

What this pr does is realizes that within a given semi-local context, e.g.:
```
<MyWidget>:
    text: self.food
    Widget:
        id: widget
        name: root.x
        text: self.name
```

within this MyWidget rule, only self changes between the sub-rules. So we can make a single environment for each `MyWidget` and then just change `self` as required e.g. for `text: self.name`, and `text: self.food`.

Following is `kivy.tools.benchmark` measured for the pr vs master.

```
                                                                      master		pr
 1/8  Core: button creation (10000 * 10 a-z)                       10.911340	10.084179
 2/8  Core: button creation (10000 * 10 a-z), with Clock.tick      13.392324	12.043900
 3/8  Core: label creation (10000 * 10 a-z)                        8.698841		7.663148
 4/8  Core: label creation (10000 * 10 a-z), with Clock.tick       9.706271		9.643000
 5/8  Widget: creation (10000 Widget)                              2.876973		2.338695
 6/8  Widget: creation (10000 Widget + 1 root)                     3.318428		2.709817
 7/8  Widget: event dispatch (1000 on_update in 10*1000 Widget)    0.064078		0.066589
 8/8  Widget: empty drawing (10000 Widget + 1 root)                0.000691		0.000669

Result:                                                             48.968945	44.549997
```

The pr should be fairly harmless otherwise. The only potential place of issue is with templates, but I did not see anything wrong with filechooser.