Skip to content
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

I have optimized the code #32

Open
wants to merge 9 commits into
base: master
Choose a base branch
from

Conversation

sandeepkalra
Copy link

New Code uses strings builder to do at least 50% faster processing.

sandeepkalra and others added 4 commits May 30, 2017 22:35
Added Go Impl.
…g object everytime,

rely on strings.builder for doing the work on the given object. The builder does not provide a way to insert
in front, so we have to reverse the whole thing later.
This was referenced Jun 14, 2018
@ocram
Copy link
Contributor

ocram commented Jun 14, 2018

Thanks!

Could you perhaps just add the chars in the reverse order again, instead of requiring a whole additional function reverseChars?

Moreover, what’s reverseRunes? It doesn’t seem to be used at all.

And, again, are the two Codec blocks necessary?

@sandeepkalra
Copy link
Author

The string builder and byte builder do NOT give access to the internal array to push in reverse order. So, I have to reverse it after the string is built from it. In my benchmarking, I found that this may be taking 30-40% of total CPU when it comes to Encode(). I will continue to search for better options, but overall this solution is 55% faster than the original where I was using "string" in for loop.

@sandeepkalra
Copy link
Author

sandeepkalra commented Jun 14, 2018 via email

Go/shortUrl.go Outdated
i := strings.Index(Alphabets, string(c))
if i < 0 {
return 0, fmt.Errorf("Invalid character %s in input %s", string(c), path)
} else {

Choose a reason for hiding this comment

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

There is no need for else, also it is not idiomatic from what I know.

Go/shortUrl.go Outdated
func Decode(path string) (int, error) {
n := 0
for _, c := range path {
i := strings.Index(Alphabets, string(c))

Choose a reason for hiding this comment

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

I think you can use strings.IndexRune, you already have the rune as c, this way you can get rid of the (string) cast.

Go/shortUrl.go Outdated
* + proof against offensive words (removed 'a', 'e', 'i', 'o' and 'u')
* + unambiguous (removed 'I', 'l', '1', 'O' and '0')
**/
package ShortURL

Choose a reason for hiding this comment

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

Where are the unit tests?

@bgadrian
Copy link

To write in reverse I think the only way is to use a normal slice of Runes, based on the specific usage of the function (we have a limited, known set of runes) we should not have any problem (ones that are fixed by bytes.buffer and strings.builder). I think if the performance gained is significant it worth the change (from builder to slice).

The Grow formula is the same (2*n), for the builder internal slice and for a regular slice, so memory allocation should no differ, but we will eliminate 3 casts (string, bytes, string) and n/2 swap operations (from the reverse).

Go/shortUrl.go Outdated
const (
Alphabets = "23456789bcdfghjkmnpqrstvwxyzBCDFGHJKLMNPQRSTVWXYZ-_"
Base = len(Alphabets)
)

Choose a reason for hiding this comment

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

Do we need to export Alphabets and Base?

Choose a reason for hiding this comment

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

All the other implementations (at least PHP,Java) have them public, so for the compatibility sake so Go too?

I would imagine it would be nice to have them as public, maybe some web servers need to do some white listing, or dynamic routing based on them?

@bgadrian
Copy link

As for the test you can use 2 other implementations with some random numbers, and use those as a test in the Go version.
Also you can add the examples from the Readme and calculate the first values by hand.
3141592 <=> vJST 123456789 <=> pgK8p

I am surprised that no other implementation has tests, so Go must be better.

@ocram ocram mentioned this pull request Feb 7, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants