Skip to content

math.big: faster radix_str() #24666

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 2 commits into from
Jun 8, 2025
Merged

math.big: faster radix_str() #24666

merged 2 commits into from
Jun 8, 2025

Conversation

tankf33der
Copy link
Contributor

@tankf33der tankf33der commented Jun 7, 2025

Faster conversion of limbs to radix.

Had to split the function into two. They are very similar, as it should be.
Each solves its specific tasks.
Now a larger number of digits is calculated at once.

Performance for radix 10:
o) -current -> 9 times faster;
o) 0.4.10 -> 57 times faster;

Tested against GMP for all radixes in range 2-36.

Copy link

Connected to Huly®: V_0.6-23024

@enghitalo
Copy link
Contributor

Can you share the benchmark code?

@tankf33der
Copy link
Contributor Author

Can you share the benchmark code?

Sure :)
Please check and share result.

http://pb1n.de/?4455b5

@spytheman
Copy link
Member

With this slightly modified version of the linked code:

import math
import math.big
import benchmark

fn main() {
	mut x := u32(math.pow(3, 2))
	x = u32(math.pow(4, x))
	mut y := big.integer_from_int(5)
	mut b := benchmark.start()
	for _ in 0 .. 5 {
		_ := y.pow(x)
		b.measure('y.pow(x) loop')
	}
	y = y.pow(x)
	b.measure('y.pow(x)')
	str := y.str()
	b.measure('y.str()')
	// println(y)

	println('5^(4^(3^2)) has ${str.len} digits: ${str[..20]} ... ${str[str.len - 20..]}')
	assert str[..20] == '62060698786608744707'
	assert str[str.len - 20..] == '92256259918212890625'
}

on master:

#0 10:33:35 ^ master ~/v>v -cc tcc run x.v
 SPENT   179.234 ms in y.pow(x) loop
 SPENT   178.036 ms in y.pow(x) loop
 SPENT   166.351 ms in y.pow(x) loop
 SPENT   194.824 ms in y.pow(x) loop
 SPENT   171.393 ms in y.pow(x) loop
 SPENT   165.913 ms in y.pow(x)
 SPENT 42602.998 ms in y.str()
5^(4^(3^2)) has 183231 digits: 62060698786608744707 ... 92256259918212890625
#0 10:34:25 ^ master ~/v>
#0 10:34:36 ^ master ~/v>v -prod -cc clang-18 run x.v
 SPENT    34.503 ms in y.pow(x) loop
 SPENT    32.460 ms in y.pow(x) loop
 SPENT    37.107 ms in y.pow(x) loop
 SPENT    39.480 ms in y.pow(x) loop
 SPENT    36.140 ms in y.pow(x) loop
 SPENT    32.663 ms in y.pow(x)
 SPENT 23459.021 ms in y.str()
5^(4^(3^2)) has 183231 digits: 62060698786608744707 ... 92256259918212890625
#0 10:35:16 ^ master ~/v>

... while on the branch of this PR:

#0 10:35:16 ^ master ~/v>gh pr checkout 24666
remote: Enumerating objects: 6, done.
remote: Counting objects: 100% (6/6), done.
remote: Total 6 (delta 5), reused 6 (delta 5), pack-reused 0 (from 0)
Receiving objects: 100% (6/6), 1.02 KiB | 1.02 MiB/s, done.
Resolving deltas: 100% (5/5), completed with 5 local objects.
From github.com:vlang/v
 * [new ref]               refs/pull/24666/head -> radix_str
Switched to branch 'radix_str'
#0 10:35:47 ^ radix_str ~/v>
#0 10:35:48 ^ radix_str ~/v>v -cc tcc run x.v
 SPENT   170.928 ms in y.pow(x) loop
 SPENT   167.950 ms in y.pow(x) loop
 SPENT   166.826 ms in y.pow(x) loop
 SPENT   185.182 ms in y.pow(x) loop
 SPENT   165.408 ms in y.pow(x) loop
 SPENT   164.608 ms in y.pow(x)
 SPENT  5781.445 ms in y.str()
5^(4^(3^2)) has 183231 digits: 62060698786608744707 ... 92256259918212890625
#0 10:35:57 ^ radix_str ~/v>
#0 10:35:58 ^ radix_str ~/v>v -prod -cc clang-18 run x.v
 SPENT    33.097 ms in y.pow(x) loop
 SPENT    36.810 ms in y.pow(x) loop
 SPENT    31.755 ms in y.pow(x) loop
 SPENT    32.860 ms in y.pow(x) loop
 SPENT    36.864 ms in y.pow(x) loop
 SPENT    32.579 ms in y.pow(x)
 SPENT  3313.222 ms in y.str()
5^(4^(3^2)) has 183231 digits: 62060698786608744707 ... 92256259918212890625
#0 10:36:11 ^ radix_str ~/v>

@tankf33der
Copy link
Contributor Author

In principle, I agree with these suggestions and will make a new push.

@tankf33der
Copy link
Contributor Author

tankf33der commented Jun 8, 2025

New push contains all suggestions + cap for st arrays.

update: tested against gmp too.

@spytheman spytheman merged commit cecbc72 into vlang:master Jun 8, 2025
70 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.

3 participants