X Tutup
Skip to content

bpo-32147: Improved perfomance of binascii.unhexlify().#4586

Merged
serhiy-storchaka merged 6 commits intopython:masterfrom
sir-sigurd:unhexlify-performance
Feb 26, 2018
Merged

bpo-32147: Improved perfomance of binascii.unhexlify().#4586
serhiy-storchaka merged 6 commits intopython:masterfrom
sir-sigurd:unhexlify-performance

Conversation

@sir-sigurd
Copy link
Copy Markdown
Contributor

@sir-sigurd sir-sigurd commented Nov 27, 2017

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Py_CHARMASK returns values in the range [0, 255], so this table needs to be 256 bytes long. See for example _Py_ctype_tolower.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Sorry for not noticing this earlier: this isn't needed, because Py_CHARMASK already does the cast. You can just use table_hex[Py_CHARMASK(argbuf[i])].

@sir-sigurd sir-sigurd force-pushed the unhexlify-performance branch 2 times, most recently from 076fda7 to d6d2365 Compare November 27, 2017 13:37
@sir-sigurd sir-sigurd force-pushed the unhexlify-performance branch from d6d2365 to 4215f0a Compare November 27, 2017 13:41
Copy link
Copy Markdown
Member

@serhiy-storchaka serhiy-storchaka left a comment

Choose a reason for hiding this comment

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

_PyLong_DigitValue could be used also in binascii.a2b_qp.

self.assertEqual(s, u)
self.assertRaises(binascii.Error, binascii.a2b_hex, t[:-1])
self.assertRaises(binascii.Error, binascii.a2b_hex, t[:-1] + b'q')
self.assertRaises(binascii.Error, binascii.a2b_hex, bytes([255, 255]))
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Add tests for b'0G', b'G0', b'0g' and b'g0'.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It's on to you. Since your initial code shared the table with binascii.a2b_qp I thought that you perhaps want to keep the relation between binascii.a2b_hex and binascii.a2b_qp.

It is better to not squish intermediate commits. Squishing them makes reviewing harder.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@serhiy-storchaka, sorry I removed my previous comment. I'll modify PR to use _PyLong_DigitValue in binascii.a2b_qp a bit later.

(ascii_data[in+1] >= '0' && ascii_data[in+1] <= '9'))) {
/* hexval */
ch = hexval(ascii_data[in]) << 4;
ch = _PyLong_DigitValue[ascii_data[in]] << 4;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

What if replace the above checks with _PyLong_DigitValue[ascii_data[in]] < 16 && _PyLong_DigitValue[ascii_data[in+1]] < 16 (with saving intermediate results in variables)?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Yes, exactly. What were the problems with this?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It becomes slower than it was for some reason.
Before:

$ ./python -m timeit -s "from binascii import a2b_qp; b = b'=AF'*2**20" "a2b_qp(b)"
100 loops, best of 5: 3.39 msec per loop

After:

$ ./python -m timeit -s "from binascii import a2b_qp; b = b'=AF'*2**20" "a2b_qp(b)"
100 loops, best of 5: 3.72 msec per loop

@@ -0,0 +1 @@
:func:`binascii.unhexlify` is now up to 2 times faster.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Add "Patch by your name." Add your name in Misc/ACKS.

@sir-sigurd sir-sigurd force-pushed the unhexlify-performance branch from 78f937e to d42cb6d Compare January 13, 2018 16:36
Copy link
Copy Markdown
Member

@serhiy-storchaka serhiy-storchaka left a comment

Choose a reason for hiding this comment

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

Sorry, I forgot to merge this PR before 3.7b1. @ned-deily, is it good to backport this minor optimization to 3.7? I didn't merge it in November just because I wanted to find the opportunity to apply the same optimizations in other code, not because there were any doubts about it.

@serhiy-storchaka serhiy-storchaka added the performance Performance or resource usage label Feb 26, 2018
@ned-deily
Copy link
Copy Markdown
Member

ned-deily commented Feb 26, 2018

@serhiy-storchaka, I don't think we should be considering backporting something like this at this point in the 3.7 cycle when it has not even landed in master yet and had buildbot exposure. Let's get it in there first.

@serhiy-storchaka serhiy-storchaka merged commit 6b5df90 into python:master Feb 26, 2018
@sir-sigurd sir-sigurd deleted the unhexlify-performance branch February 26, 2018 20:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

performance Performance or resource usage

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

X Tutup