-
Notifications
You must be signed in to change notification settings - Fork 6
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
Perf: unicode-data-names #110
Conversation
Results (Linux x64, 8 × AMD Ryzen 5 2500U, GHC 9.2.7):
|
How does it compare to ICU? |
About 5 times faster. However I did not check much the implementation. It does not rely on a reliable library as |
@harendra-kumar Any idea how to allow failure of GHC-head in the CI? Only results I got are ongoing discussions to implement the feature but no temporary fix. How could we mark it as always succeeding? We should then always check the details. |
Use |
ce623d6
to
e0ebf65
Compare
I updated the CI. We should probably use |
It will save on resources, by cancelling all CIs on first error, but it will not show you errors in all CIs. |
e0ebf65
to
62e6331
Compare
I added 2 optional APIs: Latests benchmarks:
|
5904a4a
to
871e6f2
Compare
@harendra-kumar I am statisfied with the current state, although there are some points that surprise me:
Anyway, the perf is already good and I spent a good amount of time on this, so if there is no suggestion to improve these, I think we can merge as it is. Note: this time the benchmarks are run on a smaller set of characters:
So the results cannot be compared with the previous ones. Latest benchmarks:
|
Well, I gave a final try: going low lovel with primops proved to be more efficient than FFI. The downside is that if primops or
These low-level stuff could be applied to New benchmark results, which show
|
, text >= 2.0 && < 2.1 | ||
include-dirs: cbits | ||
c-sources: cbits/icu.c | ||
cc-options: -Wall -Wextra -pedantic |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should use some optimization option e.g. -O2
or -Ofast
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, these are added automatically when passing -O2
to Cabal, which I always do. cabal check
complains about them in the .cabal
file.
-fwarn-identities | ||
-fwarn-incomplete-record-updates | ||
-fwarn-incomplete-uni-patterns | ||
-fwarn-tabs |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you try using -O2
if that makes any impact on perf?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I always run cabal
with -O2
.
name :: Char -> Maybe String | ||
name = fmap unpack . DerivedName.name | ||
name (C# c#) = case DerivedName.name c# of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My only concern is that we are making the implementation significantly more complex to make these performance gains. Is the performance gain required for unicode-data-names? Are these APIs to be used at places where the additional performance matters? Maybe that is the reason why ICU performance is not so good, because they do not care about the perf of these APIs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have the same concern about Text/ByteString APIs. If the performance does not matter just the String APIs are enough. More APIs add significantly more maintenance overhead.
I know I am a bit late about this, you have done a lot of hard work on this. But in general we should optimize only if it matters. I do not have much idea where these APIs are used, so I might be wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- The hard work is already done! It was a good exercise to start with a package with relatively small API. Next come
unicode-data
. - You should not worry about the special cases for the names. These are specific (huge) ranges of characters related to CJK. Any addition with the same template will be processed automatically, because I designed the generator and the optimisation to require no maintenance effort. Any new template will be treated as standard name; a manual change would be required only if optimisation is worth it; else it will work normally.
- The implementation is quite similar for the 3 APIs.
- It is not only about speed perf, but also about library/executable size.
- You suggested from the beginning to use
CString
s. The current code is not a simple lookup any more and requires byte arrays manipulation. So it seems quite natural to use the standardbytestring
andtext
, doesn’t it? - The only maintenance I see is updating at each new Unicode version. The Text and ByteString API rely on internal modules of third-party libs, but these are already considered almost public and seem quite stable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can also mark the new API as experimental and without guarantee to be maintained.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As the author of this package, I would like to have the best performance, but obviously I will not be optimising it forever. This is only the first round after its creation and I am very glad with it.
I am also the current maintainer, so it is designed with low maintenance effort in mind.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok. I went through the code only at a high level. Did not dig deep into details. I am assuming your tests will cover any issues.
Would have been nice if we had a single interface which could be adapted to string/bytestring/text. And the users of this library themselves could do it. We are using internals of bytestring/text so whenever they change we will have to adapt to the change. And it is unlikely that users will use these flags. You are enthusiastic and have time at this point, but at some point of time you will get busier and this will become hard for you to maintain. But I will leave this to your judgement, and I know it can be removed if we cannot maintain it.
name :: Char -> Maybe String | ||
name = fmap unpack . DerivedName.name | ||
name (C# c#) = case DerivedName.name c# of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok. I went through the code only at a high level. Did not dig deep into details. I am assuming your tests will cover any issues.
Would have been nice if we had a single interface which could be adapted to string/bytestring/text. And the users of this library themselves could do it. We are using internals of bytestring/text so whenever they change we will have to adapt to the change. And it is unlikely that users will use these flags. You are enthusiastic and have time at this point, but at some point of time you will get busier and this will become hard for you to maintain. But I will leave this to your judgement, and I know it can be removed if we cannot maintain it.
c8b25cd
to
2349c54
Compare
Rebased |
2349c54
to
4d34300
Compare
Encode the explicit length of the aliases. Add filter “WithNameOrAlias” to benchmark [skip ci]
Create internal experimental package `icu`.
Previously we skipped the entire test on Unicode version mismatch between ICU & `unicode-data`, but we can run the test for all characters defined in both libs.
4d34300
to
e8dd9f6
Compare
We should use |
Follow-up of #107.
Added comparison to ICU.