By Developers, For Developers
PDF Pg | Paper Pg | Type | Description | Fixed on | Comments |
---|---|---|---|---|---|
15 | TYPO | “As usual with thse measurements” | 2015-04-14 | ||
24 | ERROR | In the signal1.rb example, commenting out the ‘trap(“TERM”)’ line does not change the output: ObjectSpace still reports one LargeObject instance. However, if I change do_something to allocate two or more LargeObject instances, all but one of them do get garbage collected if the trap line is absent. | 2015-05-05 | Thanks! \n \nThe problem is that in Ruby 2.2 you need to force it to perform the major GC, like this: \n \n GC.start(full_mark: true, immediate_sweep: true) \n \nOtherwise, the object may be marked, but not swept. \n \nI've also found that Ruby 2.1 doesn't need to be forced. When I wrote this chapter, I used 2.1 and didn't notice this behaviour. \n | |
26 | TYPO | In the second part of each_bang.rb, it should probably create instances of Thing instead of instances of Object for consistency with the first part. Also, it should probably count the instances in the same way, (“ObjectSpace.each_object(Thing).count ”instead of “ObjectSpace.count_objects[:T_OBJECT]”). | 2015-05-05 | Thanks! Corrected. | |
29 | TYPO | On iPhone5 screen, page 29/424 “To get an rough idea of how things” Should probably be “a rough idea”. | 2015-05-07 | ||
37 | ERROR | On iPhone5 screen, page 37 / 424 “On Linux and Mac OS you can get RSS from the ps command” Strictly speaking, it should be Mac OS X, to be able to use `ps`. There are a couple other places in the book, but not always referring to commands. | 2015-05-07 | ||
61 | TYPO | On iPhone5 screen, page 61 / 424 “you will have to run the wrapper several time” Should be “several times” | 2015-05-07 | ||
172 | TYPO | On iPhone5 screen, page 172 / 424 “to treat it as an craft” -> a craft “precidely” -> precisely | 2015-05-07 | ||
222 | ERROR | On iPhone5 screen, page 298 / 424 “String#downcase! doesn’t even appear” It should probably be “upcase!” here. | 2015-05-07 | ||
331 | SUGGEST | On iPhone5 screen, page 331 / 424 “PostgreSQL - the most often used database server in the Ruby on Rails world” Would you have some reference to back up the claim? I see no problem in removing the whole sentence, actually (note: I am a PostgreSQL user :-) ) | 2015-05-07 | Agree, that was too strong of a statement. Fixed. \n \nThanks for this and all other reports. I do appreciate your time that you spent reading so closely. | |
336 | SUGGEST | On iPhone5 screen, page 336 / 424 “Forking ensures that any memory allocations happen in child process only” This will not work on standard Windows installation. Perhaps a simple mention and suggestion to use batch / PowerShell can suffice at this point. | 2015-05-29 | ||
344 | TYPO | On iPhone5 screen, page 344 / 424 “Yes, that is a shortcut, but an useful one” Not sure, but I would write “a useful one”. | 2015-05-07 | ||
54 | TYPO | arrag_agg instead of array_agg | 2015-05-28 | Fixed. Thanks, Jennifer | |
31 | TYPO | “I made the map block more verbose to show you whether the problem is” Page 31, paragraph 1 should read “I made the map block more verbose to show you where the problem is” | 2015-06-10 | ||
211 | TYPO | “That is already 4.6x faster. But avoiding regular expressions altogether is even more faster” Middle of page, should read: “That is already 4.6x faster. But avoiding regular expressions altogether is even faster” | 2015-07-08 | ||
31 | ERROR | (A slightly nitpicky erratum here, forgive me, but I did hesitate for a moment wondering if I was missing something.) In the description of how to parse dates more efficiently, it says “A better solution is to let the date parser know which regular expression to use”. This implies that strptime() takes a regular expression, but it doesn’t, it takes a format string. I think this occurrence of “regular expression” and the one further down the page, “avoiding regular expressions altogether is even more faster”, should be replaced with something more accurate like “template” or “date format”. Also, in that second quote, it should read just “faster” instead of “more faster”. | 2015-07-08 | ||
26 | SUGGEST | The code snippet chp2/each_bang.rb actually uses a while loop, so this code snippet might stand to be renamed. | 2015-07-08 | Thanks, Chris. I'll probably leave it as is, because internally each! is a while statement anyways. | |
35 | TYPO | In the psql code at the bottom of the page it looks like the # symbol is causing the syntax highlighter to make the \\timing command and select statement look like comments. | 2015-07-08 | ||
41 | TYPO | The psql vs Active Record memory usage comparison says “ActiveRecord uses 3.5x more memory.” The psql method shows 11 MB of memory and AR shows 33 MB, so that should be “3x more memory”. | 2015-07-08 | I compare 33MB to the size of the data, which is 9.5MB. So it is almost 3.5x | |
43 | TYPO | When creating the minions table, the text says: “Run the migration with bundle exec rake db:migrate and you will get 10 Minions for each Thing in the database.” This needs to be run with RAILS_ENV=production so that the table is created in the production database, otherwise the code that follows won’t work. | 2015-07-08 | Yeah, good catch! | |
43 | ERROR | This is more of a technical discrepancy than an error. When I ran the two ActiveRecord calls to load all the Minions for all Things, I actually got better memory performance with the second one: {2.2.1 MB"}} {2.2.1 MB"}} The text shows an increase in memory usage for the second, but running this under Rails 4.2.3 I got the results shown above. Perhaps Rails 4.2 has made improvements in this area? | 2015-07-08 | Looks like it. I'll investigate why. Meanwhile, I've changed the explanation a bit to not emphasize the memory usage increase. | |
47 | TYPO | The first line of this snippet is missing the closing pipe: |object| <% objects.each do |object %> | 2015-07-08 | ||
48 | ERROR | The Rails partial rendering example says: “That also performs two orders of magnitude better.” The numbers quoted for Rails 4.x are 1.840 s and 0.100 s. That’s about 20x faster, but “two orders of magnitude” would be 100x faster. | 2015-07-08 | Good catch, thanks. The text referred to the (incorrect) measurement I did a while ago. I fixed the numbers, but forgot to update the explanation. | |
50 | TYPO | “They take both time and memory, so be careful when using them in a loop, especially with link_to url_for and img_tag.” There should be a comma between “link_to” and “url_for”. | 2015-07-08 | ||
8 | TYPO | I made the map block more verbose to show you whether the problem is. s/b I made the map block more verbose to show you where the problem is. | 2015-07-28 | ||
54 | SUGGEST | The link to KCachegrind in the footnote seems to be to an old page. Since I can’t include links in errata, all I can say is that the old page has a link to the new page, and that should probably be substituted in. | |||
55 | ERROR | Using ruby-prof version 0.15.9 (on Ruby 2.2.4p230), in order to get the final line of chp4/ruby_prof_example_api1.rb printing the result of the FlatPrinter to the file, I had to slightly change the syntax, otherwise I ended up with an empty file. The API is `RubyProf::AbstractPrinter#print(output = STDOUT, options = {})`, so I needed to change `printer.print(File.open(“ruby_prof_example_api1_profile.txt”, “w+”))` to `printer.print(File.open(“ruby_prof_example_api1_profile.txt”, “w+”), {})` | |||
71 | SUGGEST | Call Graph rendering didn’t work for me out of the box using QCacheGrind on Mac OSX, so I would suggest adding in some extra installation instructions for the Graphviz library on each platform. In order for me to get the graphs rendering, I needed to perform the following steps: $ brew install graphviz The symlink was because QCacheGrind couldn’t seem to find where dot was. Since the call graphs are great, I really think that adding extra installation information where possible would go far to prevent disappointment when you say you’re just about to show “the most useful [graph] in KCachegrind”, yet you just get error messages and have to go searching for a solution to render them properly. | |||
74 | SUGGEST | class AppTest < MiniTest::Unit::TestCase is now class AppTest < MiniTest::Test in Minitest 5.8. | |||
55 | ERROR | ruby: 2.3.0 This line `printer.print(File.open(“ruby_prof_example_api1_profile.txt”, “w+”))` I needed to change it to: `File.open(“ruby_prof_example_api1_profile.txt”, “w+”) { |file| printer.print(file) }` I tried: `printer.print(File.open(“ruby_prof_example_api1_profile.txt”, “w+”), {})` but that didn’t work either. | |||
41-42 | ERROR | Command passes gc: :disable, but results showgc with a gc_count: 1. If GC is disabled, gc_count should be 0. = 2.2.0 :001 > Measure.run(gc: :disable) { Thing.all.load } {"2.2.0":{"gc":"enable","time":0.32,"gc_count":1,"memory":"33 MB"}} => nil = INVALID COMPARISON === “This uses 5 times less memory and runs 1.5 times faster than Thing.all.load.” (Comparing 33 MB to 7 MB) This is an invalid comparison as the first command runs without GC and is 33 MB, while the 2nd command runs with GC and reports 7 MB, but also has a gc_count of 1. When testing these commands myself, I get something more like the following: === 2.2.0 :001 > Measure.run (gc: :disable) { Thing.all.select([:id, :col1, :col5]).load } With, gc_count: 0 on both memory is only half the amount of memory on the 2nd command, not 5 times. | |||
15 | SUGGEST | “Let’s use the wrapper to run our unoptimized code example from the previous chapter” but then the sample code has nothing to do with the mentioned example from the previous chapter. The structure of the “data.csv” file used in the example is not shown anywhere and that makes it hard to reason about it. | |||
161 | TYPO | Small typo. Instead of “Now that you how Ruby allocates, …” should be “Now that you know how Ruby allocates…” | |||
102 | ERROR | Page 101 lists GC Time(ms) as 0.755 in the GC profiler report, but page 102 says “the single collection pass took almost 800 ms”, which is 1000 times that value. (I hope I’m looking in the right place, but I can’t see what else the almost 800 ms could be referring to.) | |||
116 | TYPO | Missing word between “to” and “the performance” in this fragment: “Should the test find a slowdown, we want to the performance before and after, and their difference.” | |||
80 | ERROR | The description of chp5/app_optimized3.rb is incorrect/misleading in that it includes Regexp#initialize calls. However, the Regexp’s do not include any interpolation, so ruby generates one static regexp during compilation and uses it for all calls to the function, it does not initialize a new regexp per method call. This is true as far back as ruby 1.8, and probably even true before that, as I believe perl operates similarly. Example, best tested with irb: ObjectSpace.count_objects[:T_REGEXP]
| |||
106 | SUGGEST | For the trick that works on Linux to clear the filesystem cache, use just echo instead of sudo echo. If you require passwords for sudo and don’t support tickets, using sudo echo and sudo tee is going to require two password prompts, and the echo command does not need superuser privileges. | |||
160 | ERROR | When describing memsizes of objects, the book says that the extra byte for strings that can’t be stored in the ruby object is for “upkeep”. That is incorrect, the extra byte is so the string is null terminated, so you can pass the string to C str* functions that expected null terminated strings without worrying about SIGSEGV (not that that is a good idea). All bytes for upkeep are stored inside the object. | |||
14 | SUGGEST | On printed page 14, in file chp2/wrapper.rb there are two invocations to GC.start as follows: GC.start This second form (with options) seems to not be used anywhere else in the book, and looks like it is a leftover that was meant to be removed. | |||
117 | SUGGEST | It seems somewhat strange that the methods which are meant to help readers establish their own peformance testing/benchmarking routines (specifically the methods: measure, performance_benchmark and assert_performance) are not coded in the performance-aware way that is discussed in the book. (One could argue that they are helper functions not intended for high performance, but neverthless it was an obvious opportunity to show performance-aware code, which was missed.) | |||
17 | ERROR | If you want to modify an array in place, you need only to modify each of its elements in place. data.each{|str|str.upcase!} When bench-marked, I averaged 0.107 vs 0.109 with data.map!{|str|str.upcase!} Barely any difference, but still… map! is not really doing anything after str.upcase!. | |||
88-89 | TYPO | In the sentence “For example, how do we know that heap_page_allocate represents Ruby object creation?”, “heap_page_allocate” should be replaced by “heap_assign_page”. |