flame bait: execution speed Perl vs. C (Date::Calc::PP vs. Date::Calc::XS)
Dear Module Authors, recently in one of the Amsterdam Perl Mongers meetings the question came up how much faster actually the XS version of Date::Calc (Date::Calc::XS) was as compared to the Pure Perl version (Date::Calc::PP). Here is the answer (see attached script - you will need to have Date::Calc 6.3 and Date::Calc::XS 6.2 installed to run this script successfully): FreeBSD 7.2.-stable: $ perl benchmark.pl Running under Date::Calc::PP version 6.3 timethis 5000: 17.3147 wallclock secs (17.24 usr + 0.06 sys = 17.30 CPU) @ 288.94/s (n=5000) Running under Date::Calc::XS version 6.2 timethis 5000: 1.02551 wallclock secs ( 0.97 usr + 0.06 sys = 1.03 CPU) @ 4848.48/s (n=5000) Windows XP SP3: Running under Date::Calc::PP version 6.3 timethis 5000: 17.1034 wallclock secs (16.86 usr + 0.00 sys = 16.86 CPU) @ 296.58/s (n=5000) Running under Date::Calc::XS version 6.2 timethis 5000: 1.3329 wallclock secs ( 1.28 usr + 0.00 sys = 1.28 CPU) @ 3900.16/s (n=5000) Another (faster) Windows XP SP3 machine: Running under Date::Calc::PP version 6.3 timethis 1: 20.5605 wallclock secs (20.55 usr + 0.00 sys = 20.55 CPU) @ 486.69/s (n=1) Running under Date::Calc::XS version 6.2 timethis 1: 1.44224 wallclock secs ( 1.42 usr + 0.00 sys = 1.42 CPU) @ 7032.35/s (n=1) One can see from these results that the XS version quite consistently runs approximately about 15 times faster than the PP version. The test script benchmarks a function which calls all functions in Date::Calc once, each. Other similar results from XS/PP pairs of modules would be interesting - maybe not for any practical purposes, but just for the fun of it (or maybe to give deciders convincing arguments to upgrade to an XS version or not). Cheers, Steffen benchmark.pl Description: Binary data
Re: flame bait: execution speed Perl vs. C (Date::Calc::PP vs. Date::Calc::XS)
It might be seen as flame bait because there have been endless discussions on the Perl vs. C execution speed issue on Perl newsgroups in the past. :-) 2009/11/18 Kartik Thakore thakore.kar...@gmail.com Maybe he thought there were a debate on XS v.s PP performance. If only we could be this flame retardent in the uneeded perl5 v.s perl6 debate. On 18-Nov-09, at 7:29 AM, Aristotle Pagaltzis pagalt...@gmx.de wrote: This is flame bait? Why is this flame bait?
Re: Why you don't want to use /dev/random for testing
Dear Jonathan, thanks a lot for the link to this very interesting article! However, a more useful graphical representation of the quality of PRNG’s would be to take consecutive pairs of random numbers as the (X,Y) coordinates of a point to plot. Non-uniform distributions are then easily visible to the naked eye. It is hard to see any quality differences in the graphs accompanying this article which are essentially big red rectangles. It is impossible to see with the naked eye whether the fluctuations in these graphs are simply due to randomness or to a shortfall of the associated algorithm. Does someone here happen to have the necessary plotting software at hand to provide these pictures, without too much effort? That would be great! Thank you! Best regards, Steffen 2009/11/11 Jonathan Yu jonathan.i...@gmail.com I should note, I wrote an article on this awhile back. Take it with a grain of salt, as I'm not an expert in the area; I just wrote bindings for the ISAAC algorithm to Perl. http://jawnsy.wordpress.com/2009/06/04/performance-of-mathrandomisaac/ It compares the performance of multiple different PRNG modules (code for this is in the Math::Random::ISAAC examples/ directory). I've included charts of the distributions generated by them and benchmarks of course.
Re: How to best detect availability of C compiler in Makefile.PL?
Hello Aristotle, I'll answer below: 2009/11/3 Aristotle Pagaltzis pagalt...@gmx.de * O. STeffen BEYer ost...@gmail.com [2009-10-13 15:30]: I'd rather have the user decide what he/she wants, as in this attached file. That’s the wrong way to think about it. OK, hyperbole; it’s not *wrong*. But it’s very incomplete. Don’t forget that there are a lot of people who might merely want to use some Perl program, and unlike you and me, they *aren’t* Perl programmers. They are merely users of some random Perl code that uses your module. Most of these users don’t care which version of your module gets installed, and if you ask them to pick one anyway, they won’t know how to decide, either. All they know is they want the program they care about to work. To these people, the option you want to offer is not helpful. It is, in fact, a bewildering obstacle. Yes, I agree. This is one of the reasons why I have adopted the common approach of Date::Calc being the pure Perl module, and Date::Calc::XS the plug-in needing a C compiler. Another reason was that you would not know which version had been tested in CPAN::Testers. And still another reason was that when giving support, it would be extremely hard to find out which version the user was using. I would have needed the user to jump through hoops to get this information. So for them, you have to provide sensible defaults for all options. (And if there isn’t any strong reason to offer an option That was actually the case (or is - see version 6.1 of Date::Calc!). The presence of a suitable compiler was determined, and then Makefile.PL explicitly said what was recommended. By just hitting Return, the user would get the recommended option. in the first place, it shouldn’t even be an option. But that’s just a sidenote, since in your case there is solid reason.) That means your module should just check for a compiler and install with the XS variant by default if possible. The option to change that should be provided in such a way that opinionated users can get at it without forcing other users to care. (This is probably best achieved by checking some environment variable in your *.PL, since that passes down easily through the CPAN shell, whereas taking a switch would force more manual monkeying.) * O. STeffen BEYer ost...@gmail.com [2009-10-13 23:05]: Since Date::Calc is such a low-level basic module, it should be especially backward compatible, so that even people in old production environments (never fix what ain't broken) can upgrade my module and benefit from new functions, without having to install a load of other modules first - which their company policies would probably not permit. If they can install Date::Calc, how come they can’t or won’t install other modules? OK, maybe they can’t install XS modules. I can see that. But if they can install *your* pure-Perl module, why can’t they install other pure-Perl modules also? This is not the first time I see this argument and I never understood it. *headscratch* Sometimes they can get permission for one module, or at least a well-defined list of a few modules, but not for an endless list of modules and dependencies (which the user frequently does not know exactly in advance). And permission does not mean that they can install the module(s) themselves, no, it means that the administrator is going to install the module(s) for them. So the less work this administrator has to do, the more likely to get his/her permission (if he/she has the power to decide that, as is sometimes the case in certain companies). And it may be even more difficult to get permission from a manager who hasn't a clue what the user is talking about, and the less the manager sees a security risk, the better. So the fewer modules, the better. Do you understand it now? :-) Best regards, Steffen
Re: Date::Calc 6.x and Date::Pcalc 6.x
Hi Jonathan, and hi to everybody else who might also be concerned: Hi Steffen: I was upgrading the package for Date::Calc available in Debian (libdate-calc-perl) recently and came across the following message in your CHANGES.txt: + United Date::Calc and Date::Pcalc into a single distribution Similarly, there is an identical note in the CHANGES.txt for Pcalc as well. What confuses me about this is that the packages still look to be separate upstream, and my inference from your changelog entry was that the packages should be merged (ie, Date::Calc also contains date::Pcalc), which is not currently the case. Would you mind elaborating on this further? Thanks for releasing your work to the CPAN. Cheers, Jonathan Answer: Date::Calc 6.0: Just Date::Calc as it always used to be (C library plus XS wrapper plus PM modules), only with some updates (language is not a global anymore, new normalized mode) Date::Pcalc 6.0: Just Date::Pcalc as it always used to be (pure-Perl version), complete rewrite based on Date::Calc 6.0 Date::Calc 6.1: contains Date::Calc 6.0 AND Date::Pcalc 6.0. Depending on availability of a C compiler and user choice, will install either of the two, INTO THE Date::Calc NAMESPACE. Date::Pcalc 6.1: contains Date::Calc 6.0 AND Date::Pcalc 6.0. Depending on availability of a C compiler and user choice, will install either of the two, INTO THE Date::Pcalc NAMESPACE. (This allows to upgrade existing Date::Pcalc installations to a faster C/XS version without any changes to existing code) So Date::Calc 6.1 and Date::Pcalc 6.1 are indeed merged - they're just two slightly differently flavoured embodiments of the same merge Installing both allows to test e.g. on a machine with C compiler the code that is being developed for a machine without. It is also meant to give users more choice as to which upgrade path they prefer. Date::Calc 6.2 is essentially the same as Date::Calc 6.1, but without the C/XS part (it will now always install a pure-Perl version, Date::Calc::PP), the C/XS part has been outsourced in Date::Calc::XS 6.2 Date::Calc 6.2 is now a wrapper which tries to load Date::Calc::XS 6.2, if available, and failing that, defaults to Date::Calc::PP. Does that make it clearer? Sorry for the confusion! Best regards, Steffen
Re: How can I tell MakeMaker to insert recommended modules into META.yml?
In the meantime I found out when this META_MERGE tag works and when not: When I run a tool from the terminal which calls make dist, everything works fine. When I run the same tool from within a cron-job, with stdout and stderr redirected (to a file and /dev/null, respectively), the extra tags in META.yml disappear! Looks like a bug to me... Best regards, Steffen (P.S.: Why do I run the tool from within a cron-job, you may wonder? Because when doing a make dist, I touch all files and directories first. It turns out that the size of the dist file varies quite a bit depending on this time stamp on all files and dirs! So I re-run the make dist every minute and keep the new dist file if it is smaller. That costs me (or better, Ralf :-) ) a bit of CPU time, but when several thousand people download the file, this saves some bandwidth!) 2009/10/16 O. STeffen BEYer ost...@gmail.com In the meantime, I found this: http://use.perl.org/articles/08/09/06/1541246.shtml And with trial and error, I found out this (META_MERGE is the keyword I was looking for and couldn't find in any of MakeMakers documentation files): WriteMakefile( 'META_MERGE'= { 'recommends' = { 'Carp::Clan' = 6.01, 'Date::Calc::XS' = 6.2 } }, 'NAME' = 'Date::Calc', 'VERSION_FROM' = 'lib/Date/Calc.pm', 'ABSTRACT_FROM' = 'lib/Date/Calc.pod', 'PREREQ_PM' = { 'Carp::Clan' = 5.3, 'Bit::Vector' = 7.1 }, 'AUTHOR'= 'Steffen Beyer st...@cpan.org', 'dist' = { COMPRESS = gzip -9, SUFFIX = gz } ); However, for unknown reasons, this worked once, but later the recommends section in META.yml disappeared again. Oops?!?! And I still wonder how I can tell MakeMaker to produce more complex structures such as this: optional_features: - opt_csv: description:Provides parsing of CSV streams requires: Text::CSV_XS:0.43 recommends: Text::CSV: 1.12 Text::CSV_PP:1.20 Text::CSV_XS:0.65 - opt_excel: description:Provides parsing of Microsoft Excel files requires: Spreadsheet::ParseExcel: 0.26 Spreadsheet::ParseExcel::FmtDefault: 0 recommends: Spreadsheet::ParseExcel: 0.49 Which is supposed to allow the user to make a better informed decision whether or not to install certain recommended additional features/modules. Any hints on all that? Many thanks in advance!!! Cheers, Steffen 2009/10/16 O. STeffen BEYer ost...@gmail.com How can I tell MakeMaker to insert recommended modules into META.yml? When I edit META.yml manually, the next time I run make dist, MakeMaker generates META.yml anew and discards my entries. What is the right option for WriteMakefile() to tell it that there are modules which are not required but recommended? Thank you!!! Best regards, Steffen
Re: How can I tell MakeMaker to insert recommended modules into META.yml?
Hi Jonathan, in principle, you are completely right! And yet, in this case you are wrong! I also do not want my users to have to answer questions; neither do I want to have to myself. BUT: Date::Calc used to be a high-performance module, based on a C library. Now Date::Calc isn't anymore, it is a wrapper and normally comes with a pure-Perl implementation plug-in (Date::Calc::PP). If you want to have the fast module that it used to be, you now have to install Date::Calc::XS on top, in an additional step. And I wanted the optional requirement in Date::Calc to notify users that installing Date::Calc::XS was strongly recommended (if you can, i.e., if you have a C compiler on your machine). Moreover, for reasons of backward compatibility with earlier Perl versions (5.005_03 and older, for instance), Date::Calc comes with a requirement for Carp::Clan 5.3 (which runs on these older Perl platforms). Carp::Clan 6.02 actually also works on Perl 5.005_03, but the tests don't pass, because they need Test::More, which requires Perl 5.6. However, whenever you can, it is recommended to install Carp::Clan 6.02, which has a bugfix that Carp::Clan 5.3 doesn't. It's not that Carp::Clan 5.3 would not work, it's just that its output is uglier than it should be. Again, I would like to notify the users that although only Carp::Clan 5.3 is required, version 6.02 is actually recommended. You see? No answering questions, just informing the users of some important changes! Cheers, Steffen 2009/10/17 Jonathan Rockway j...@jrock.us * On Fri, Oct 16 2009, O. STeffen BEYer wrote: Any hints on all that? Wow, a lot of people CC'd on that message. That is probably Considered Annoying to the people you sent it directly to. Anyway, optional requirements probably aren't the *worst idea ever conceived*, but they are close. When your module depends on optional modules, my module can't just say, requires Foo::Bar, it has to say requires Foo::Bar and whatever modules one would need to make your optional features work. This may change from version to version, making it impossible to ship a reliable module that depends on yours. It is also a problem when communicating with others; when I ask someone to try Foo::Bar, I now need to tell them exactly which combination of optional modules to install also. If I can remember. Finally, detecting which features to enable at runtime can be flaky. Imagine you have a module that enables an optional feature when Foo::Quux is installed. I don't want that feature when I install the module, so I skip installing the prereq. For a while, your module works fine. Some time in the future, I install Foo::Quux to satisfy the dependencies for Gorchify::It, and suddenly, your module stops working due to auto-detecting Foo::Quux, enabling an optional feature, and then not working the same way anymore. Very bad. Modules should not work differently based on whether or not other random modules happen to be in @INC. The solution is to make each optional feature a separate distribution; then it's easy to depend on the optional feature, easy to remove if you don't want it, and easy to communicate to others. Also, I can tell you one thing that nobody wants to do while installing CPAN modules, and that's answer questions. I want to say cpan Foo and go away and not monitor the terminal it's running in to see if it's asking me questions like Do you want to install the module that you requested to install? [y]. No... I don't want to install the module I just invoked cpan -i on... thanks for asking... To summarize: Optional requirements considered harmful. Regards, Jonathan Rockway -- print just = another = perl = hacker = if $,=$
How can I tell MakeMaker to insert recommended modules into META.yml?
How can I tell MakeMaker to insert recommended modules into META.yml? When I edit META.yml manually, the next time I run make dist, MakeMaker generates META.yml anew and discards my entries. What is the right option for WriteMakefile() to tell it that there are modules which are not required but recommended? Thank you!!! Best regards, Steffen
Re: How can I tell MakeMaker to insert recommended modules into META.yml?
In the meantime, I found this: http://use.perl.org/articles/08/09/06/1541246.shtml And with trial and error, I found out this (META_MERGE is the keyword I was looking for and couldn't find in any of MakeMakers documentation files): WriteMakefile( 'META_MERGE'= { 'recommends' = { 'Carp::Clan' = 6.01, 'Date::Calc::XS' = 6.2 } }, 'NAME' = 'Date::Calc', 'VERSION_FROM' = 'lib/Date/Calc.pm', 'ABSTRACT_FROM' = 'lib/Date/Calc.pod', 'PREREQ_PM' = { 'Carp::Clan' = 5.3, 'Bit::Vector' = 7.1 }, 'AUTHOR'= 'Steffen Beyer st...@cpan.org', 'dist' = { COMPRESS = gzip -9, SUFFIX = gz } ); However, for unknown reasons, this worked once, but later the recommends section in META.yml disappeared again. Oops?!?! And I still wonder how I can tell MakeMaker to produce more complex structures such as this: optional_features: - opt_csv: description:Provides parsing of CSV streams requires: Text::CSV_XS:0.43 recommends: Text::CSV: 1.12 Text::CSV_PP:1.20 Text::CSV_XS:0.65 - opt_excel: description:Provides parsing of Microsoft Excel files requires: Spreadsheet::ParseExcel: 0.26 Spreadsheet::ParseExcel::FmtDefault: 0 recommends: Spreadsheet::ParseExcel: 0.49 Which is supposed to allow the user to make a better informed decision whether or not to install certain recommended additional features/modules. Any hints on all that? Many thanks in advance!!! Cheers, Steffen 2009/10/16 O. STeffen BEYer ost...@gmail.com How can I tell MakeMaker to insert recommended modules into META.yml? When I edit META.yml manually, the next time I run make dist, MakeMaker generates META.yml anew and discards my entries. What is the right option for WriteMakefile() to tell it that there are modules which are not required but recommended? Thank you!!! Best regards, Steffen
Re: How to best detect availability of C compiler in Makefile.PL?
Hello David, yes, I had understood that, but I failed to be more explicit about the problems with legacy platforms: Often, newer modules are not installed on them, AND/OR newer modules may not even work on legacy platforms due to their using Perl features which are newer and not available on older platforms. For instance, I am regularly testing all my modules with Perl 5.005_03 before each release. And they still work on it. Out of the box. Cheers, Steffen P.S.: In the meantime, I have adopted the proposed solution with ExtUtils::CBuilder. See also the attached Makefile.PL. 2009/10/14 David Cantrell da...@cantrell.org.uk On Tue, Oct 13, 2009 at 11:01:56PM +0200, O. STeffen BEYer wrote: Also, many of your suggestions need Perl modules to be installed on the target machine which do not exist on legacy Perl installations ... Devel::CheckLib is designed to be bundled with your distribution. -- David Cantrell | top google result for internet beard fetish club You know you're getting old when you fancy the teenager's parent and ignore the teenager -- Paul M in uknot Makefile.PL Description: Binary data
How to best detect availability of C compiler in Makefile.PL?
Dear Perl module authors, what would be the best way to detect whether a working C compiler is available at build time of a module (i.e., in Makefile.PL)? I would like to install a (faster) XS version of a module if that is the case, and a (slower) pure-Perl implementation if not. Remember that C compilers are not always available on all systems. Sometimes they cost heavy extra money, or sometimes you have to work with what's there on a customer's or provider's server (where frequently installing a C compiler is not an option due to company policies). Thank you! Best regards, Steffen Beyer http://www.engelschall.com/u/sb/download/ http://search.cpan.org/author/STBEY
Re: How to best detect availability of C compiler in Makefile.PL?
Hi Ryan, thanks a lot for your fast response (see a copy at the bottom of this message for convenience)! But how would I then test both module versions (Date::Calc and Date::Pcalc) with the same test suite, without duplicating code? And how would I rely on the Perl version in the C/XS version if something goes wrong? Something along these lines? package Date::Calc; BEGIN { eval { require bytes; }; } use strict; use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $VERSION); @ISA = qw(Exporter DynaLoader); @EXPORT = qw(); @EXPORT_OK = qw( ... ); %EXPORT_TAGS = (all = [...@export_ok]); $VERSION = '6.1'; BEGIN # otherwise this comes too late for imports from this module { require Exporter; require DynaLoader; eval { bootstrap Date::Calc $VERSION; }; if ($@) { local($^W) = 0; # avoid subroutine redefined warnings for the three subroutines below eval { require Date::Pcalc; Date::Pcalc-import(':all'); }; if ($@) { die Can't find neither the dynamically loadable library for Date::Calc nor its pure-Perl substitute Date::Pcalc!\n; } else { warn Unable to find the dynamically loadable library for Date::Calc, falling back to its pure-Perl substitute Date::Pcalc!\n; } } } sub Decode_Date_EU2 { ... Another thing I am wondering about: You wrote: if something changes later on the module will always continue to work I am wondering _what_ could change later (or go wrong), and if it would be the right thing to do to (silently?) fall back to the pure-Perl version - maybe even without a warning to the user. If the Calc.dll (or shared library Calc.so) disappears, this almost certainly indicates that there is something seriously wrong, which should be cried about loud and fixed before continuing. Or if somebody installs a newer Perl version over an existing one, this could break binary compatibiliy. But I wonder if the eval bootstrap above would be able to catch that. Anyway: In the meantime, I found a way how to detect the compiler in Inline.pm. See the attached Makefile.PL to see how this would work with Date::Calc. I am reluctant to install the Perl version no matter what, as you suggested; I'd rather have the user decide what he/she wants, as in this attached file. Any opinions on all this, anyone? Cheers, Steffen 2009/10/13 Ryan Voots simcop2...@yahoo.com On Tuesday 13 October 2009 06:17:47 O. STeffen BEYer wrote: Dear Perl module authors, what would be the best way to detect whether a working C compiler is available at build time of a module (i.e., in Makefile.PL)? I would like to install a (faster) XS version of a module if that is the case, and a (slower) pure-Perl implementation if not. Remember that C compilers are not always available on all systems. Sometimes they cost heavy extra money, or sometimes you have to work with what's there on a customer's or provider's server (where frequently installing a C compiler is not an option due to company policies). While I've got no idea about detecting the compiler, I would suggest though installing the pure perl one no matter what, under a different name and having the module fall back on it if possible, that way if something changes later on the module will always continue to work. This could also simplify the build and install process since you wouldn't have to decide which one to copy during make install. Makefile.PL Description: Binary data
Re: How to best detect availability of C compiler in Makefile.PL?
Thanks a lot for all your valuable hints! I had a brief look at all of them. It seems that most of them are a bit overkill for what I want, or would mean some ugly messing with the symbol table through exporting imported identifiers. I like the straightforward approach that the user can choose at build time to install either implementation, and can always come back on his decision. Once the C version is installed, there is no reason to go back to the Perl version - but it's possible (e.g. for testing of code destined for a pure-Perl machine). Also, many of your suggestions need Perl modules to be installed on the target machine which do not exist on legacy Perl installations. Since Date::Calc is such a low-level basic module, it should be especially backward compatible, so that even people in old production environments (never fix what ain't broken) can upgrade my module and benefit from new functions, without having to install a load of other modules first - which their company policies would probably not permit. ExtUtils::CBuilder though seems a real winner, maybe I'll include this as an optional way to determine that the C compiler is really present and working, falling back to the method of scanning %Config and $ENV{PATH} if this module is not available. But first of all, I'll give it some more thought! Thanks again to you all! Cheers, Steffen