Skip to content

Improve io.ascii guessing performance and usability #2881

Description

@taldcroft

As noted in #2877, in guessing mode the memory and speed of io.ascii has room for improvement. Some quick ideas:

  • Register a callback to give applications a way to monitor progress
  • Short-circuiting of failed guesses. The pure Python code can end up reading the entire table for each guess before deciding if it was OK (as long as no exception gets raised first).

Activity

  1. added this to the v1.0.0 milestone on Aug 20, 2014
  2. embray commented on Aug 21, 2014

    @embray
    Member

    The short-circuiting sounds like a good idea. I had something like that in mind too but I'm not quite sure how it would work.

    Since most tables are going to be line-oriented anyway maybe it could start by reading just a few lines and trying to figure things out. That won't work for everything, such as tables containing string values that contain newlines (ugh). But it would be good for a first-pass (maybe falling back on reading the full table only if nothing else is found).

  3. taldcroft commented on Dec 20, 2014

    @taldcroft
    MemberAuthor

    This is still an issue, where here out is a 10000 row table with 5 columns:

    In [59]: timeit t2 = ascii.read(out)
    10 loops, best of 3: 76.8 ms per loop
    
    In [60]: timeit t2 = ascii.read(out, format='basic')
    100 loops, best of 3: 5.89 ms per loop
    

    One easy fix is documentation, e.g. putting in a highlighted Note box in the Getting started => Reading tables section which reminds people to use the format (which is frequently basic) for any biggish files.

    The second is a little more complicated, but perhaps there could be a max_rows argument to the readers which would limit the number of data rows that get read in. This is independent of data_end. Then in the guessing process there could be a two-pass guess of first trying the table with max_rows=100 and only if that succeeds go on to the full table.

    cc: @hamogu @mdmueller

  4. astrofrog commented on Dec 21, 2014

    @astrofrog
    Member

    I like the idea of limiting the number of rows read in during guessing.

  5. hamogu commented on Dec 21, 2014

    @hamogu
    Member

    Since we currently read the table into an array once before the guessing starts, it is easy to just pass a shortened version of the stay to the readers.
    @taldcroft are you working on it? Otherwise I'll do that over Christmas so that we can still get it into 1.0 as a bug fix (just pushing the boundaries not to call it a feature here...). If it is as easy as I think it is after looking at the code this does not require more that a dozen lines of code.
    I only need to give some more thought to testing...

  6. taldcroft commented on Dec 21, 2014

    @taldcroft
    MemberAuthor

    I don't think that passing a shortened version of the input lines is robust because you might have an input with 1000 lines of comments. There really needs to be another parameter max_rows that finds its way into the data reader. BTW max_rows is a very useful enhancement on its own as an addition to the top-level API. This was recently added to np.genfromtxt (or at least was discussed on the list).

  7. hamogu commented on Dec 21, 2014

    @hamogu
    Member

    I was envisioning two new configuration parameters with sensible defaults so that most people don't have to care about them, but if you have a table that is special, then you have the option to fiddle with it:

    • max_rows_guessing would define how many rows are passed in to the guessing process. I think 1000 is a sensible default value. Most tables will not have that many comment lines. Once is passes guessing with 1000 rows, the guessing would attempt to read the whole table with the same format and if that fails (e.g. the first 1000 rows happen to look like a csv, but then there is no commas at all on line 1001) it would continue guessing.
      Clearly, trying a shortened version of the table first and than a the full version introduces a new overhead, and only makes sense if the table is significantly longer than max_rows_guessing.
    • use_max_rows_guessing would set the the minimum number of rows where the max_rows_guessing is attempted. I'm thinking of 5000 as default start value, but the best value clearly depends on how many columns you have, if one of the fast readers succeeds, etc.

    @taldcroft : In which situation, that is not addressed by data_end already, would you benefit from max_rows?

  8. taldcroft commented on Dec 21, 2014

    @taldcroft
    MemberAuthor

    In which situation, that is not addressed by data_end already, would you benefit from max_rows?

    The usual reason I have used data_end is to chop off cruft at the end of the data file, typically with a negative value. So I think of data_end as related to specifying the format of the input data file, while max_rows is a generic concept of limiting data rows. Admittedly the use of a non-default data_end to clip cruft is not a terribly common case and otherwise it's possible to use data_end to have the same effect. So we can leave things at that without adding max_rows.

    I'm good with your idea of a config param max_rows_guessing. I think that in 98% of files you can tell by the first 100 rows, but we don't need to decide on that now. However, it's important that this parameter apply to rows of data actually read in the reader and not just clipping input data lines. It doesn't matter if most files don't have 1000 lines of comments because some will. I just don't like implementations where there is an obvious path to failure. Yes, the user can change their config for that one file, but most won't figure that out. Better to make the code do the right thing.

  9. taldcroft commented on Dec 21, 2014

    @taldcroft
    MemberAuthor

    The reason I was thinking about a smallish number for max_rows_guessing is that we can just always do that and not worry about use_max_rows_guessing.

  10. modified the milestones: Future, v1.0.0 on Jan 13, 2015
  11. taldcroft commented on Apr 17, 2015

    @taldcroft
    MemberAuthor

    Another idea just discussed with @hamogu would be a standard fast_identify method which, if available, will quickly identify content that could be valid for the reader type. It doesn't have to be 100% accurate, i.e. false positives are OK, but false negatives would not be OK. This is related to the discussion in #3693.

  12. removed this from the Future milestone on Apr 8, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions