Skip to content

Use ifNil: in isShorter:than:. #99

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
Feb 22, 2025
Merged

Use ifNil: in isShorter:than:. #99

merged 7 commits into from
Feb 22, 2025

Conversation

fniephaus
Copy link
Contributor

@fniephaus fniephaus commented Feb 12, 2025

I'd argue this is slightly more idiomatic and it seems that this is also supported in SOM. In fact, the Squeak/Smalltalk compiler turns ifNil: into an identity check (== nil) plus jump rather than sending isNil to the receiver and then jump.

I noticed this some time ago when I looked into excessive splitting in TruffleSqueak (here's
a recent example
). It turned out that the additional isNil send causes these splits.

Surely, there are ways to fix the splitting issue in TruffleSqueak. I just thought I open this anyway because, again, it is more idiomatic and because of that, also specifically optimized by the Squeak/Smalltalk compiler.

Instead of `isNil ifTrue:`.
@smarr
Copy link
Owner

smarr commented Feb 12, 2025

Looking at the other languages, I think the change should be fine.

Happy to merge it, but would prefer to keep the SOM and SOMns benchmarks in sync with the Smalltalk ones.

And yeah, the splitting issue, you probably still want to fix :)

@fniephaus
Copy link
Contributor Author

Oh right, the SOM impl is separate. For some reason, I thought it’s derived from the Smalltalk code. I pushed another commit.

Signed-off-by: Stefan Marr <[email protected]>
@eregon
Copy link
Contributor

eregon commented Feb 12, 2025

FWIW I recall that we did similar for Ruby but everywhere: 8ccc0c9 (for idiomatic code reasons mostly, .nil? avoids splitting on TruffleRuby).
With some follow-ups later to change e.g. if liter.parent == nil into unless liter.parent as suggested by RuboCop.

@eregon
Copy link
Contributor

eregon commented Feb 12, 2025

There are a few more isNil ifTrue:, probably it would be good to change them too:
https://github.com/search?q=repo%3Asmarr%2Fare-we-fast-yet%20%2FisNil%20ifTrue%3A%2F&type=code

@krono
Copy link
Contributor

krono commented Feb 13, 2025

Note that some of these are newspeak, but the reasoning shouldn't be different.

@krono
Copy link
Contributor

krono commented Feb 13, 2025

The reason of ifNil: not being used yet is that the original SOM, from which the benchmarks where pulled and built upon, did not support ifNil: back then.
Times are different now :)

@fniephaus
Copy link
Contributor Author

There are a few more isNil ifTrue:, probably it would be good to change them too:
https://github.com/search?q=repo%3Asmarr%2Fare-we-fast-yet%20%2FisNil%20ifTrue%3A%2F&type=code

After looking at other usages, I'm not so sure anymore how far we want to go here. There are, for example, isNil ifTrue: [] ifFalse: [] usages, which I would change to ifNil: [] ifNotNil: [], but that's not supported in SOM. Then, there also are usages of notNil ifTrue: [], which should probably be changed to ifNotNil: [], which is supported in SOM.

Any thoughts?

@smarr
Copy link
Owner

smarr commented Feb 13, 2025

Yeah, I pushed the SOMns commit, mostly to indicate that it's also separate code.
And, I didn't immediately merge it, because as @eregon pointed out, it would make things inconsistent. When looking at what we did for the other languages, it seemed desirable to apply this consistently to all benchmarks.

That some variations are currently missing from SOM seems only a small hurdle. Though, it's a bit of extra work. @OctaveLarose, for SOM-RS, did you implement special handling for Boolean>>#ifNil:*? I think I may have it for some of the SOMs already but not consistently.

@OctaveLarose
Copy link

som-rs doesn't have ifNil, no. But it looks like it could be a speedup in a few benchmarks, and I could easily implement it. A lot of the code takes inspiration from PySOM's design, and I don't think it has any primitives for it, either.

It sounds like a good change, though! I'd not realized it was a common case.

Signed-off-by: Stefan Marr <[email protected]>
Signed-off-by: Stefan Marr <[email protected]>
Signed-off-by: Stefan Marr <[email protected]>
@smarr
Copy link
Owner

smarr commented Feb 13, 2025

The update for SOM is here: SOM-st/SOM#123

The dev branch is really the main branch. The release branch is very old…
Also switch to Ubuntu 24.04 and set JAVA_HOME.

Signed-off-by: Stefan Marr <[email protected]>
@smarr
Copy link
Owner

smarr commented Feb 22, 2025

Performance difference on the SOM implementations without specific support for ifNil:* variants: https://rebench.dev/Are-We-Fast-Yet/compare/2e1a50989356d8beb32c55393c8c2087d7f77707..a31e167bf1d6812a2251e10321d81abf0a3fab54

It looks a bit noisy, and there might be some extra overhead compared to the inlined isNil ifTrue:* version on List and Havlak.

With inlining of ifNil:* and variants, it seems a bit noisy and unclear, but no major change:
https://rebench.dev/Are-We-Fast-Yet/compare/2e1a50989356d8beb32c55393c8c2087d7f77707..807f8d81edef384d50638b82b80da6cb0f9e4775

@smarr smarr merged commit ec02893 into smarr:master Feb 22, 2025
11 checks passed
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.

5 participants