Skip to content

update width calculations #48

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

Merged
merged 7 commits into from
Apr 10, 2025
Merged

Conversation

emar-kar
Copy link
Contributor

@emar-kar emar-kar commented Apr 8, 2025

Closes #6

I was trying to improve performance in grid calculation and switch from rows to columns to fix the related issue

@emar-kar
Copy link
Contributor Author

emar-kar commented Apr 8, 2025

@tertsdiepraam here is the MR I was talking about. And to update ls do I'll wait for the release of the library.

@tertsdiepraam
Copy link
Member

Uh oh, looks like I was just touching the same code 😄 I'll look at this tomorrow.

@tertsdiepraam
Copy link
Member

I'm frankly amazed this works for TopToBottom too. I was just it didn't but it works because we don't reference num_columns in the compute_dimensions for TopToBottom. It's a bit strange. I'm gonna have to poke at this for a bit, because I think there will be some strange edge cases. This is always such hard code to reason about fully.

@emar-kar
Copy link
Contributor Author

emar-kar commented Apr 9, 2025

It calculates the number of possible columns first using the terminal width and widest possible cell content. I thought it's more relevant, since both of the values are given and it can be the "worst" case scenario e.g. all names are the size of widest. Then it tries to increase the number of columns and see if the potential_dimension, which calculates columns widths according to print direction still fits into the terminal width.

I was just it didn't but it works because we don't reference num_columns in the compute_dimensions for TopToBottom.

compute_dimensions calculates the width of the cells according to the direction and it does not use num_columns in TopToBottom because it is the index of the element in cells vector.

If you can come up with some edge cases I didn't think about it would be great, thx

Copy link
Member

@tertsdiepraam tertsdiepraam left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right! I've looked much more into this now and I think I have a better grasp of what you've done. In short: it's fantastic! However, it does need a lot of improvements in terms of variable names and comments. I've got a commit where I was doing that for myself, so with your permission I'd like to push that to this branch. I also included more tests.

There are some other issues. The is_complete and width functions are now broken because columns can now have 0 widths in some columns for TopToBottom. We should investigate whether uutils and eza use those (I don't think so), so we can remove them.

I think you've also solved #39, because you're assuming balanced columns. Which seems to match what GNU is doing:

> ls --width=6
aaa
bbb
ccc
d

In current uutils-term-grid, this would be printed as

aaa  d
bbb
ccc

But that is unbalanced and kind of ugly. The reason I suppose that this was done in the first place is that it is technically "more optimal" in terms of line count.

All in all, consider me impressed! Do I have your permission to push to this branch?

@emar-kar
Copy link
Contributor Author

emar-kar commented Apr 9, 2025

@tertsdiepraam Yeah, sure. If you need to push something, you are more than welcome to

@tertsdiepraam
Copy link
Member

Whoo it finally works. For some reason git had a really hard time pushing to this branch. It's mostly updating some names and comments.

Even tho it fixed the issue I just realized that I drastically increased the number of computations. I'll have a look into this part more later. But if you have any suggestions, just push those

I set a maximum number of columns of self.cells.len(), but otherwise I don't have any great ideas. How are you measuring the performance?

@tertsdiepraam
Copy link
Member

There's actually another algorithm I was thinking of for the LeftToRight direction, which might speed things up again.

Basically we can just start building the first row until we hit the maximum width. This gives us a pretty good maximum number of columns. Then we just decrease the number of columns and calculate the dimensions each time until we find the first one that fits.

For the TopToBottom direction we can then maybe also be a bit smarter by specializing for it. We would need to split the computation for both. Maybe an idea for another PR? Then we'll merge this, then make a PR splitting the two directions and then we can optimize them separately.

@emar-kar
Copy link
Contributor Author

emar-kar commented Apr 9, 2025

How are you measuring the performance?

I'm using hyperfine on uu_ls to see if the change of the crate does not affect performance there. But my take here was to reduce calls to compute_dimensions as much as possible.

Basically we can just start building the first row until we hit the maximum width. This gives us a pretty good maximum number of columns.

I think this one can be tricky with edge cases. We can definitely try this approach to see if it will be more efficient than the one with using the max width.

For the TopToBottom direction we can then maybe also be a bit smarter by specializing for it. We would need to split the computation for both. Maybe an idea for another PR? Then we'll merge this, then make a PR splitting the two directions and then we can optimize them separately.

Actually I was also thinking in this direction, to split the computations for every direction. It will grand more flexibility on improving individual parts, instead of coming up with something common for everything. Plus, there was a request to add RightToLeft direction. If we split these two now, IMHO it will be easier to add support for another the same way.

@tertsdiepraam
Copy link
Member

tertsdiepraam commented Apr 10, 2025

I have an idea to improve TopToBottom slightly I think. Instead of checking each number of columns we do this:

current_rows = div_ceil(cells, current_cols)
next_rows = current_rows - 1
next_columns = div_ceil(cells, next_rows)

I think (but have to check) that this will skip possibilities that lead to empty columns at the end

@tertsdiepraam tertsdiepraam self-requested a review April 10, 2025 07:58
Copy link
Member

@tertsdiepraam tertsdiepraam left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Merging so we can make a new branch for splitting it up!

@tertsdiepraam tertsdiepraam merged commit 07d49c4 into uutils:main Apr 10, 2025
7 checks passed
Copy link

codecov bot commented Apr 10, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 0.00%. Comparing base (c8db34b) to head (b2d435b).
Report is 1 commits behind head on main.

Additional details and impacted files
@@    Coverage Diff     @@
##   main   #48   +/-   ##
==========================
==========================

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Fill up rows as much as possible in LeftToRight direction
2 participants