{"action":"closed","issue":{"url":"https://api.github.com/repos/l3kn/stumpy_png/issues/1","repository_url":"https://api.github.com/repos/l3kn/stumpy_png","labels_url":"https://api.github.com/repos/l3kn/stumpy_png/issues/1/labels{/name}","comments_url":"https://api.github.com/repos/l3kn/stumpy_png/issues/1/comments","events_url":"https://api.github.com/repos/l3kn/stumpy_png/issues/1/events","html_url":"https://github.com/l3kn/stumpy_png/issues/1","id":168548581,"number":1,"title":"Optimizations","user":{"login":"asterite","id":209371,"avatar_url":"https://avatars.githubusercontent.com/u/209371?v=3","gravatar_id":"","url":"https://api.github.com/users/asterite","html_url":"https://github.com/asterite","followers_url":"https://api.github.com/users/asterite/followers","following_url":"https://api.github.com/users/asterite/following{/other_user}","gists_url":"https://api.github.com/users/asterite/gists{/gist_id}","starred_url":"https://api.github.com/users/asterite/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/asterite/subscriptions","organizations_url":"https://api.github.com/users/asterite/orgs","repos_url":"https://api.github.com/users/asterite/repos","events_url":"https://api.github.com/users/asterite/events{/privacy}","received_events_url":"https://api.github.com/users/asterite/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":2,"created_at":"2016-08-01T01:00:27Z","updated_at":"2016-08-06T18:24:04Z","closed_at":"2016-08-06T18:24:04Z","body":"Hi again!\r\n\r\nFirst of all: this shard is awesome, thank you!!\r\n\r\nI wanted to do this challenge: https://www.reddit.com/r/dailyprogrammer/comments/4v5h3u/20160729_challenge_277_hard_trippy_julia_fractals/\r\n\r\nI did it, but then I needed to generate an image. I remembered seeing your project and I said \"let's try it\". I just had to read the \"write\" example from the README to make it work, and it worked out of the box, and it was super fast! I love it when that happens :-)\r\n\r\n<details>\r\n<summary>Here's the program, in case you want to try it (compile with `--release` because otherwise it's a very slow)</summary>\r\n```cr\r\nrequire \"complex\"\r\nrequire \"stumpy_png\"\r\n\r\ndef f(z)\r\n  z*z - 0.221 - 0.713.i\r\nend\r\n\r\ndef compute(pix)\r\n  i = 0\r\n  loop do\r\n    pix = f(pix)\r\n    i += 1\r\n    break if pix.abs >= 128\r\n  end\r\n  i\r\nend\r\n\r\nwidth = 1920\r\nheight = 1200\r\n\r\nmatrix = Array.new(width) { Array.new(height, 0) }\r\nmax = 0\r\n\r\nwidth.times do |x|\r\n  height.times do |y|\r\n    cx = -1.0 + (2.0/(width - 1)) * x\r\n    cy = -1.0 + (2.0/(height - 1)) * y\r\n    value = compute(cx + cy.i)\r\n    max = {max, value}.max\r\n    matrix[x][y] = value\r\n  end\r\nend\r\n\r\ncanvas = StumpyPNG::Canvas.new(width, height)\r\n\r\nwidth.times do |x|\r\n  height.times do |y|\r\n    value = matrix[x][y]\r\n    value = value.fdiv(max)\r\n    value = (255 * value).to_i\r\n    color = StumpyPNG::RGBA.from_rgb_n({value, value, value}, 8)\r\n    canvas.set_pixel(x, y, color)\r\n  end\r\nend\r\n\r\nStumpyPNG.write(canvas, \"output.png\")\r\n```\r\n</details>\r\n\r\nOn my machine it takes 2s to generate a 1920x1200 image, which is not bad at all!\r\n\r\nThen, as always, I wondered if this could be further optimized, so I started to look at the code and found several optimization opportunities. With some simple changes I was able to cut the time to 1s, and I'm sure I could even optimize it further.\r\n\r\nMost of the changes will be transparent to the user, just how data is stored internally in some types. However, there is one change that already reduces the time from 2s to 1.5s: change RGBA from a class to a struct. Having one instance in heap memory for each pixel is pretty expensive. And I think RGBA is ideal for a struct, as its size is 64 bits, so a word nowadays. However, if we do that, I'd also make it immutable to prevent someone from taking an rgba instance and modifying it, only to find out a copy was modified. So one would have to take it, create a modified instance, and put it back. I think it's a good compromise if we want to speed up things, but I wanted to know your opinion before sending a big PR changing these things."}}
{"actor":{"display_login":"l3kn"}}