On Tuesday, August 8, 2023 at 5:50:16 PM UTC+2 Edward K. Ream wrote:

On Tuesday, August 8, 2023 at 10:27:14 AM UTC-5 Edward K. Ream wrote:

>  c.all_positions_for_v shows how to generate all *positions* p such that 
p.v == v. 

This method "reconstitutes" positions using only VNode operations. But this 
trick is only mildly interesting.


Maybe it is just mildly interesting to you, but it is orders of magnitude 
faster than what you propose as a "straightforward" solution. Don't believe 
me? In a tree with 100 nodes your linear search will visit 100 positions 
minus  number of v descendants multiplied by the number of found positions. 
If a v is found only once in a tree (which is most common scenario), and 
lets say v has in total 10 descendants (which is 10% of the tree), your 
solution will look in 90 positions, while c.all_positions_for_v will find a 
unique position by visiting only p.level() nodes.

Put the following script in a node inside LeoPy.leo and execute to see the 
difference for yourself:

# ======================================================
import time
allvnodes = set(z.v for z in c.all_positions())
def all_positions_for_v(v):
    for p in c.all_positions():
        if p.v == v:
            yield p.copy()

def measure(name, f):
    t1 = time.perf_counter_ns()
    for i, v in enumerate(allvnodes):
        f(v)
        dt = (time.perf_counter_ns() - t1)/1e6
        if dt > 60000:
            g.es(f'too slow: average time: {dt/i:.2f}ms')
            break
    else:
        g.es(f'Total for {name} is {dt:.2f}ms')
        g.es(f'Average for {name} is {dt/len(allvnodes):.2f}ms')


def using_p(v):
    return list(all_positions_for_v(v))

def using_v(v):
    return list(c.all_positions_for_v(v))

measure('using_v', using_v)
measure('using_p', using_p)
#--------------------------------------------------------------

On my machine this gives the following output:

Total for using_v is 148.46ms
Average for using_v is 0.01ms
too slow: average time: 26.26ms


So, the "straightforward" solution, using position generators is about 2600 
times slower than the code using only v nodes generators.


 

Instead, the following straightforward generator yields positions in 
outline order:

def all_positions_for_v(self, v: VNode) -> Generator:
    c = self
    for p in c.all_positions():
        if p.v == v:
            yield p.copy()

Afaik no part of Leo uses this code. Perhaps the PR should delete it.


The idea that generator using v nodes should be deleted because it isn't 
used, and your remark that


> - v.self_and_subtree contains no recursion and no "yield from" statements


explains a lot to me. Not that I understand why it matters to you that 
"yield from" is not being used, but I now understand a little better your 
unwillingness to accept my ideas. You just don't see how much of 
unnecessary work is being done under the hood of p generators. Yes, they 
might seem a bit shorter or perhaps more useful or more straightforward on 
the surface, but they are just hiding a lot of unnecessary complexity deep 
down, while having simple and innocent appearance.


In all my code related to Leo and outlines, I've always used short helper 
generators defined inside the body of the function that uses them. In most 
cases the resulting code was shorter and much faster than the equivalent 
code based on p generators.


I think that v generators should be used everywhere instead of the much 
slower code that is usually used, but it is your call.


Vitalije


PS: By the way, "yield from" is just a shorter form that doesn't require 
you to explicitly name item that you are yielding from the generator. Much 
like lambda allows you to define function without explicitly naming it if 
it is used in just one place.


yield from xs


# is the same as


for x in xs:

    yield x


# but doesn't require inventing a new name for item x


-- 
You received this message because you are subscribed to the Google Groups 
"leo-editor" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/leo-editor/23ea67d7-7a9a-4c6b-9b4c-0d8596c9662fn%40googlegroups.com.

Reply via email to