Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Locked thread
Mithaldu
Sep 25, 2007

Let's cuddle. :3:
Little performance question:

This runs in 5 seconds:
code:
use constant ONE => 1;
use constant ZERO => 0;
use constant TWO => 2;

my $a;

my @test = (4,2,3);
 
for (0..10000000) {
    $test[ONE]++;
    $test[ZERO]++;
    $test[TWO]++;
    $test[ONE]--;
    $test[ZERO]--;
    $test[TWO]--;
    $a = $test[ONE];
    $a = $test[ZERO];
    $a = $test[TWO];
}

This runs in 14 seconds:
code:
my $a;
  
my %test = (
            ONE =>4,
            ZERO => 2,
            TWO => 3
           );
 
for (0..10000000) {
    $test{ONE}++;
    $test{ZERO}++;
    $test{TWO}++;
    $test{ONE}--;
    $test{ZERO}--;
    $test{TWO}--;
    $a = $test{ONE};
    $a = $test{ZERO};
    $a = $test{TWO};
}
Is that normal or am i overlooking something?

Adbot
ADBOT LOVES YOU

Mithaldu
Sep 25, 2007

Let's cuddle. :3:

Fenderbender posted:

I don't know if this would be an ok place for this or anything, but my company is looking for web and application developers specializing in Perl. If you're interested, send me a PM and I'll give you some contact information.
Could you please activate the ability for other members here to email you? I don't have PM ability, but if you can accept remote workers i'd be very interested. Or, if you don't want to do that, you could give my ICQ/AIM or Yahoo ids in my profile a poke.

I figure 3+ years on a life system should be decent experience for what you want. :)

Mithaldu fucked around with this message at 14:59 on Sep 16, 2008

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
Thanks and sent. :)

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
Using ActivePerl 5.10.0 under WinXP, running this:
code:
use OpenGL;
use threads;
my $thr = threads->create(\&update_memory_use);
sub update_memory_use {}
I get this error:
code:
Can't locate package GLUquadricObjPtr for
@OpenGL::Quad::ISA at
D:\Web-Dev\dwarvis\trunk\lifevis\test.pl line 202.
Huh? It doesn't happen when i leave out the thread creation.

Mithaldu fucked around with this message at 14:24 on Sep 27, 2008

Mithaldu
Sep 25, 2007

Let's cuddle. :3:

TiMBuS posted:

It looks like OpenGL probably isn't thread-safe.

I'm far from an expert here but I think perl threads avoid sharing resources as much as possible, duplicating them when needed.
The error suggests that once OpenGL is initialized you can't clone it because there's an object (GLUquadricObjPtr) missing from OpenGL::Quad's inheritance table.. for some reason. Honestly I got no idea why this would happen.

Maybe try adding 'use threads::shared' and it might not clone the object?


PS your example works just fine on Strawberry Perl with an OpenGL module I installed with ppm (OpenGL 0.56 from http://www.bribes.org/perl/ppm)

No idea about strawberry, i use ActivePerl.

Anyhow, you're pretty much right. This fixed it:
code:
use threads;
BEGIN {
    sub update_memory_use {}
    my $thr = threads->create(\&update_memory_use);
}
use OpenGL qw/ :all /;

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
In ActivePerl PPM, you can add the trouchelle repository (if you're on 5.10.0). Have you tried the GTK module from there? It fails on install when trying to download the libatk 1.0.0 dll, but that should be a trivial matter of hunting down the correct file and putting it in /bin.

Edit: Libraries here: http://trouchelle.com/ppm/scripts/dll/ ; Glib, ExtUtils-PkgConfig, Cairo needs installed too, manually. And since GTK is retarded, you'll need to copy C:\Perl\site\lib\auto\Cairo\Cairo.dll to C:\Perl\bin, as well as http://trouchelle.com/ppm/scripts/dll/libpng12-0.dll.gz.

The synopsis example worked for me after that.

As for making an executable:
I did it by making a bin directory in my project directory which contains the perl executable and dlls. Then i added site/lib, open a command shell, sysinternals' procmon and try to run my script with "bin\perl script.pl". Procmon will tell you what files perl is looking for and if you use filters cleverly you can quickly have it weed out the ones it has found after you copied them to "site/lib" and iteratively build up a small distro for your script.

Next step would be to make sure that your sript is a module and is in some appropiately named sub-directory. Then you create a .bat file in the main directory that does the above perl call, and convert it with one of the many bat2exe tools into an executable.

Lastly, use http://www.perlmonks.org/?node_id=410030 to lose the command shell window.

You can see an example of the whole setup in action here: http://code.google.com/p/dwarvis/source/browse/trunk/lifevis

Mithaldu fucked around with this message at 15:10 on Oct 4, 2008

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
I wish any of the Profilers would work in multi-thread OpenGL applications. Either they just plain don't work, since GLUT hijacks the exit call or they only pick up the first thread my program starts, which only checks the memory use every two seconds.

Mithaldu
Sep 25, 2007

Let's cuddle. :3:

Triple Tech posted:

:( It's a shame that Devel::NTYProf doesn't work on Windows. I wonder what it's written on top of that Windows lacks?
Did a quick look at the .xs they're using and uh, it seems like they simply expect the unix time stuff? I guess the main reason there is no windows port yet is simply because they're busy with other stuff. They're even asking for people who would like to help on a windows port in the cpan page.

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
Cross-platform stuff has its way of sneaking up on you. Aside from that, just from the experience of realizing my own first project at the moment, i'd say the first priority is making it work in the first place and then branch into other stuff once you know it works. Additionally, windows programmers tend to have a good bit of knowledge about linux simply because they're geeks. Heck, many probably know enough about linux to have decided that its flaws outweigh windows'. However linux programmers often don't even have windows around in the first place, nevermind any knowledge about it.

What system call? Mind giving a bit more information? I don't have the time to commit to a completely new project now, but i would still like to let it roll around in my brainpan a bit. =)

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
"Limited" scopes aren't hard to track at all. "use strict;" and you'll never have to spend a thought about scoping at all, it just comes naturally:

- variables are either:
-- passed as input at the beginning of a block, via @_
-- created at any point in a block via my

- variables are valid:
-- from start to end of a block
-- within all blocks created inside the current block

If i remember correctly, this works the same in c, doesn't it?



As for loose typing:

Yes, it is not very efficient. However that is the ONLY criticism you can level against it, that it uses more memory than it *needs* to. In practice it allows extremely fast prototyping. Example: I have implemented, solo, next to my usual 40 hours work per week, a basic, but fully functional 3d engine, that does some seriously weird stuff in the data processing part to boot. It took me less than 25 days and there's stuff in it like 4-dimensional arrays, mixed in being number-based and associative.

Being OCD about memory-use is all good and fine, but only if memory use is actually an important factor. ;) And declarations, scoping (and in part also type, either scalar, array or hash) also happen in Perl the same as in C, as long as you follow sane programming guide lines.



I also suggest reading this: http://www.perlmonks.org/?node_id=87628
It is a bit old, being from 2001 and talks about stuff that was relevant for 5.6, but the bulk of it is still relevant. :)

Mithaldu fucked around with this message at 18:06 on Oct 13, 2008

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
You may wanna try using http://search.cpan.org/~mlehmann/Coro-4.8/Coro/Socket.pm and http://search.cpan.org/~mlehmann/Coro-4.8/Coro.pm to get parallelization. Coro allows such kinda stuff without having to gently caress around with multiple processes or Perl's horrible threads.

Otherwise just have one main script and one data getter script.

Data getter:
1. connects to server and gets registry data
2. uses Data::Dumper or Storable to serialize data
3. dumps data into time-stamp-tagged file in a certain directory

Constroller:
1. starts and spawns x getters with exec()
2. sleeps for y seconds
3. checks directory for new files and processes them if needed
4. if number of processed files not equal x -> 2.

Mithaldu
Sep 25, 2007

Let's cuddle. :3:

syphon^2 posted:

What am I doing wrong?
His example is retarded. Sleep always locks no matter what you do. In fact, the creator of this is retarded. (Yelled at me for "use warnings;" in my code and, in his words, claimed only "lesser people" need warnings.) However his code is solid.

What this thing does is basically this:

It keeps a list of all coroutines waiting in the script, with the main routine being a coroutine in itself. Each coroutine has a timer and a ready state switch. When you create a coroutine it is added to the list, as soon as you switch its state to ready, the timer starts running. Now your program proceeds as normal until you either call cede() or schedule().

cede() puts the currently running coroutine into the list, switches it to ready, then selects the coroutine that has been waiting the longest and either starts running it, or continues running it after its last cede(). schedule() does something similar, only it doesn't switch the current coroutine to ready.

Yes, this isn't actual multi-threading, since it pretty much only runs one thread on one CPU. However, if you have proper code design, which means you have a sufficient amount of schedules in your loops, and a half-way decently designed idle loop controller that switches coroutines back to ready state when they're needed, you pretty much have actual parallel processing, only it runs on one core only, instead of 2.

The nice thing here for you is this: Sockets block because they keep waiting for a response. However, now take a socket implementation that calls schedule() after every loop in its response waiter. Suddenly your main program gets all the CPU it needs to keep running and launch more sockets and all it needs to do different is call schedule often enough to have the controller reactivate the sockets so they can check if there was an answer.

The main point here is: Sockets don't lock because they keep the CPU busy, but because they're idling until something happens. What you want is to do something during the time they spend idling. Coro::Socket makes that possible.

If you're interested, you can check here for a life example: http://dwarvis.googlecode.com/svn/trunk/lifevis/Lifevis/Viewer.pm

Mithaldu fucked around with this message at 16:55 on Oct 22, 2008

Mithaldu
Sep 25, 2007

Let's cuddle. :3:

Sartak posted:

2.07, released today, does!

Hm, using ActivePerl, neither cpan nor cpanplus show it. How would i go about getting it?

Nevermind, selecting inode as mirror showed it.

Also, NYTProf doesn't work with Coro at all. Throws bunches of errors and trying to run nytprofhtml on the out file results in it trying to read the file, then crashing without even so much as a peep. Procmon shows it accessing the file and then directly jumping to the vsjitdebugger.

Mithaldu fucked around with this message at 22:41 on Nov 1, 2008

Mithaldu
Sep 25, 2007

Let's cuddle. :3:

Voltaire posted:

7 character input is a character.
You mean palindrome?

Voltaire posted:

if ($input = [9,8,7,6,5,4,3,2,1,0] == [0,1,2,3,4,5,6,7,8,9])
What the hell are you even trying to do there?

Also, they're right. All you need for this is one regexp and some ifs.

Lastly, try reading the PBP sometime, if you're going to program in it. Any coworkers will be grateful for that.

Mithaldu
Sep 25, 2007

Let's cuddle. :3:

Voltaire posted:

i have.
Why do you use 8-space tabs then and start a new line for the opening brace of your blocks?

Voltaire posted:

im not even sure where to start with this one without using split and join.
In that case i can honestly say that you need to do some studying. Read the first two chapters of this, completely: http://perldoc.perl.org/perlre.html

Oh, and if you're going to be in IT professionally, start reading this website daily, starting from now: http://thedailywtf.com

And on another note: I think the intent of the exercise is to check if you're actually a Perl programmer or a C(++/#) programmer. Perl has some really powerful tools that C programmers often don't really know about and ignore, as it also has everything they're already used to. As such C programmers trying to do Perl often do more damage than a complete Perl newbie would do.

Mithaldu fucked around with this message at 22:10 on Nov 9, 2008

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
Not a question, but something i just found out and thought i'd share:

Ever tried iterating through a hash so you could do something each value in it? The usual solution is to do:
code:
for my $key (keys %hash) {
    my $a = $hash{$key};
}
However, what if you don't actually care what the key is and ONLY care about the values? Perl provides something for that too, which is much more elegant and 4 times faster:

code:
for my $value (values %hash) {
    my $a = $value;
}

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
Am i doing something wrong or is map really slow?

code:
say scalar values %hash;

timethese( 160, {
        'map' => sub {
            my @array;
            @array = map { ++$_ } values %hash;
        },
        'loop' => sub {
            my @array;
            for my $value (values %hash) {
                push @array, ++$value;
            }
        },
    }
);

__END__

39144
Benchmark: timing 160 iterations of loop, map...
   loop: 1.5823 wallclock secs ( 1.58 usr +  0.00 sys =  1.58 CPU) @ 101.39/s (n=160)
   map: 2.81493 wallclock secs ( 2.78 usr +  0.02 sys =  2.80 CPU) @ 57.20/s (n=160)

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
2MB @ 80 line length is about 25000 lines. 50000 lines at a more likely medium length of 40. Depending on your CPU, that can make a good bit of difference. Also important to think about is: What *exactly* is it printing? How much data does it have to pull from the memory per print? How many references does it have to resolve per variable? etc. etc.


TiMBuS posted:

map performance sucks
Thanks. That's the perfect answer i needed to never again bother with map at all. :D

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
It's not a kneejerk reaction at all. For some reason i have serious problems wrapping my head around map and just plain reading it, as opposed to a for loop. My brain keeps expecting a comma or some parantheses. I also, to some extent, dislike the use of "magic variables" like $_ or functions that implicitly use it. As such, i have never seen map having any readability advantage for me at all.

Additionally i have, over the last few years, never had any need to iterate over an array, do something simple enough to fit into one line with map and then retain it while creating a new array for the output.

I have literally been looking for advantages of it over the past two weeks and aside from it being a different syntax (which is a disadvantage for me) i have found exactly none. It being slower than for only drives the nail in its coffin of uselessness for me.

TL;DR: Don't jump to conclusions and accusations so quickly, eh?

Mithaldu
Sep 25, 2007

Let's cuddle. :3:

fansipans posted:

It makes code a hell of a lot more readable ...
Not to me. Looks more like perl golf than anything else.

Edit: I think my problem is that i mentally translate every code i see into actual english sentences. That works very well for most constructs of Perl unless golfed. Map is impossible for me to translate into an english instruction.

Mithaldu fucked around with this message at 15:45 on Nov 18, 2008

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
I'm not entirely sure what you're trying to say with that, but honestly, I'd see myself as the latter kind of guy. When i read my Perl code it is really just *reading*, like one would usually do with a book. I see the code and effortlessly know the intent of the instruction. Certain things however just gently caress with that flow, so i work around them. It's not that i can't do it, it's just that they slow me down too much.


I know what it does, but that reading seems entirely backwards to my mind.
vvvv

Mithaldu fucked around with this message at 17:17 on Nov 18, 2008

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
I didn't say anything about functional programming, just about map in the context of Perl. :)

In fact, i have this on my "to read" list: http://gigamonkeys.com/book/

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
code:
my $a;
say scalar @item_offsets;

timethese( 5000000, {
        'scalar' => sub {
            $a = @item_offsets-1;
        },
        'subscript' => sub {
            $a = $#item_offsets;
        },
    }
);

__END__

39139
Benchmark: timing 5000000 iterations of scalar, subscript...
    scalar: 0.592491 wallclock secs ( 0.58 usr +  0.00 sys =  0.58 CPU) @ 8650519.03/s (n=5000000)
 subscript: 1.14776  wallclock secs ( 1.14 usr +  0.00 sys =  1.14 CPU) @ 4382120.95/s (n=5000000)
Huh. I would've thought it was the other way around. Anyone got any idea why this is as it is or whether i overlooked something?

(And in case anyone's wondering why i'm benchmarking this: This operation occurs 120000+ times in a loop that i'd optimally would like to crunch into 0.1 seconds.)

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
Never knew about that. Your explanation makes sense though, as perldoc only says it's *treated* as compile-time in respect to whether it affects other files or not.

Mithaldu
Sep 25, 2007

Let's cuddle. :3:

Voltaire posted:

code:
:barf:

For the love of christ. If you have the gall to ask people on the internet to solve your homework which the company (what company is it anyhow?) which gave you a Perl job despite you quite obviously just plain now knowing perl, then at the loving least run your poo poo through perltidy before posting it. It hurts my eyes just to look at it. [ http://search.cpan.org/~shancock/Perl-Tidy-20071205/bin/perltidy ]

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
Currently working on a web app that uses sqlite and does some heavy scrunching on market order data grabbed from a third party. Thanks to NYTProf i managed to get its runtime divided by a factor of 400, so i can only chime in on the love for it here. :D

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
Figures that three hours after the previous post i stumble upon an actual question:

I am trying to do a large number of inserts (30 chunks with ~200_000 inserts each) into an SQLite database and am looking for methods to speed that up since doing single inserts for each is pitifully slow.

So far i got this:
code:
my $csv_fh = Tie::Handle::CSV->new(
    csv_parser => Text::CSV_XS->new( {allow_whitespace => 1} ),
    file => $unpackedname,
    simple_reads => 1
);

$dbh->do("BEGIN;");

my $sth = $dbh->prepare(
    "REPLACE INTO orders ( orderid, volume, price ) "
    . " VALUES(?,?,?);"
);

while (my $order = <$csv_fh>) {
    $sth->execute(
        $order->{orderid}, $order->{volremain}, $order->{price}
    );
}
close $csv_fh;

$dbh->do("END;");
Now i was hoping to make it a bit faster by using execute_array. The code for that looks as follows and matches the example given in the DBI documentation:<br>

code:
my $csv_fh = Tie::Handle::CSV->new(
    csv_parser => Text::CSV_XS->new( {allow_whitespace => 1} ),
    file => $unpackedname,
    simple_reads => 1
);

$dbh->do("BEGIN;");

my $sth = $dbh->prepare(
    "REPLACE INTO orders ( orderid, volume, price ) "
    . " VALUES(?,?,?);"
);

my $insert_count = 0;
while (my $order = <$csv_fh>) {
    $sth->bind_param_array(
        ++$insert_count, 
        [ $order->{orderid}, $order->{volremain}, $order->{price} ]
    );
}
close $csv_fh;

$sth->execute_array( { ArrayTupleStatus => \my @tuple_status } );
    
$dbh->do("END;");
############################################################
However that creates this error message:
code:
DBD::SQLite::st execute_array failed: 84490 bind values supplied but 3 expected
Did i do something wrong or is this a limitation of SQLite? Does someone maybe have any suggestions for other ways to speed this up?

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
The reason why i'm suspecting it's an SQLite limitation is because it just plain cannot do things like this:

INSERT into table (one,two) VALUES (1,2),(2,3)

Gonna try restricting it though and see what happens.

Edit: Now i'm confused... DBD::SQLite::st execute_array failed: 1 bind values supplied but 8 expected

Edit2: Ok, looked at the documentation again. I'm a retard. I thought the binds bound data sets, but instead bind columns.

Mithaldu fucked around with this message at 16:00 on Dec 14, 2008

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
Did both of these already. :)

Also, just tried splitting it into chunks of 10000 and it added on 30% more processing time.

That's how it looks right now, and i don't think there's anything more that can be done.
code:
$dbh = DBI->connect( $cfg->param("dbi.source"), '', '', { AutoCommit => 1 } ) or make_error( $cfg->param("errors.sqlconn") );
$dbh->do("PRAGMA synchronous = OFF;") or make_error( $cfg->param("errors.sqlfail") . '<br>' . $dbh->errstr );
$dbh->do("PRAGMA temp_store = MEMORY;") or make_error( $cfg->param("errors.sqlfail") . '<br>' . $dbh->errstr );
$dbh->do("PRAGMA journal_mode = OFF;") or make_error( $cfg->param("errors.sqlfail") . '<br>' . $dbh->errstr );

use Tie::Handle::CSV;
my $csv_fh = Tie::Handle::CSV->new( csv_parser => Text::CSV_XS->new( {allow_whitespace => 1} ), file => $unpackedname ,simple_reads => 1);

$dbh->do("BEGIN;") or make_error( $cfg->param("errors.sqlfail") . '<br>' . $dbh->errstr );

my $sth = prepare_table_update();

my $order_count = 0;

while (my $order = <$csv_fh>) {
    convert_entry_dates($order);
    $order_count++;
    next if $order->{expiry} < $expiretime;
    $sth->execute( $order->{orderid}, $order->{typeid}, $order->{volremain}, $order->{price}, int $order->{expiry}, $order->{bid}, $order->{systemid}, $order->{regionid} ) or make_error( $cfg->param("errors.sqlfail") . '<br>' . $dbh->errstr );
    write_status("Downloading $queue_size files...<br> Preparing insert of $entry->{filename}...<br>$order_count/$max_orders orders...") if ($order_count % 500)==0;
}
close $csv_fh;

write_status("Downloading $queue_size files...<br>Committing $max_orders orders to database...");
$dbh->do("END;") or make_error( $cfg->param("errors.sqlfail") . '<br>' . $dbh->errstr );

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
as far as SQLite is concerned, these are all exactly the same thing:

AutoCommit=0 / commit
BEGIN / END
BEGIN / COMMIT
begin_work / commit

I've implemented all of these before and the results and benchmarks are all identical. Only reason i am using BEGIN/END is that that's what the SQLite manual talked about and it makes for good visual markers in the code.

However i'd like to hear about why begin_work / commit is better.


Triple Tech posted:

There's way too much going on there.
You mean as far as pinpointing the performance problems goes? Haven't taken it apart yet, because i'm pretty confident that i know which parts impact how much. However, I've also run it through NYTProf and the result seems pretty straight-forward: http://drop.io/3gtix2e


Triple Tech posted:

Gosh, your code is all over the place. :(

Edit for mantra: Isolate. Isolate. Isolate.
Mind explaining what you mean?

I realize i didn't spend much time making it look pretty, but i'd like to hear what more experienced people have to say anyway. :)

Mithaldu
Sep 25, 2007

Let's cuddle. :3:

Triple Tech posted:

Code should be written from both a semantic and aesthetic perspective. Design-wise, you should be telling the driver what to do, not having the driver just pass on you talking to the database directly. If the driver abstracts the concept of starting and stopping transactions, and that abstraction has no implementation penalty, then you should use it.
Alright, thanks for that. You're completely right and i should stop thinking of the driver as only being something that allows me to talk with the database.

Triple Tech posted:

For visual markers in your code, just use space, comments, and an editor with syntax highlighting.
I do, Komodo IDE is awesome. :) I guess it's some kind of commentary on how ugly this code is when i rely on the SQL statements to guide my eye. I do have to say that i usually write a lot more easily readable and that this was pretty much frankensteined together.

Triple Tech posted:

NYTProf? :shobon:
It's dead-easy, really. :)

Open the file index.html in any browser. Keep in mind it is a line-based profiler. The top table tells you how much realtime it spent on what subroutine call in what module. The table below lists it by module. DumpGetter.pm is the main module i'm working on. If you click on any report in the lower table, it shows you the time spend in the relevant things in a new page.

Triple Tech posted:

Isolation.
That's one thing i just can't quite parse at the moment. I am aware of how to write more readable code, but i am completely self-taught, so i like to hear from more experienced people in plain english what their vocabulary means. Right now all i can think of is: "Split that stuff up in more subroutines." (Which i am incidentally slightly allergic to, what with the massive overhead in subroutine calls in Perl.)

Mithaldu
Sep 25, 2007

Let's cuddle. :3:

satest4 posted:

According to your profiling, your DELETE statements are eating up way more time than the INSERTs.

If you take the DELETEs out of the equation, you are spending more time on CSV-related tasks than you are in DBI.

drat, you're right, I completely missed that. Guess i really should try parsing the files manually.

satest4 posted:

INSERTs seem pretty quick at 0.00014 seconds per query
Thanks a lot for that! The SQLite benchmarks claim that they're faster than MySQL, but the unavailablity of multi-row inserts made me doubt that. Knowing that the inserts actually compare favourably already brings me a good step ahead.

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
Working on something related to the previous question i had and stumbled upon this: Is there a way to to somehow "use" a bunch of modules with only one command? Preferrably while having said command being a subroutine imported from another file.

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
So, simply like this?
code:
package MyModule;
use MyModule::RequiredModules;
---------------------------------------------------------
package MyModule::RequiredModules;

use A;
use B;
etc.

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
drat, was hoping i did something wrong. When i do the stuff above, subs don't end up usable in MyModule when exported by "A" as follows:
code:
package A;
use base 'Exporter';
our @EXPORT = qw( lint_html extend_template_include_paths );
On the other hand, using "use base" allowed me to move all CGIApp plugins into a wrapper module, which is nifty.

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
satest4, thanks for the awesome explanation. I really should've realized that i need to export all functions that i want to carry over and i also learned something about the specifics of begin blocks. :)

As for "use base", i honestly really don't get what you're trying to say there. I DID notice that it didn't work for transporting simply exported functions, but i don't have any idea why, since i never looked into how OO internals work in Perl. However, it really IS part of the solution for my problem here, since CGI::Application plugins attach their functions to the caller when imported and thus these functions survive the "use base" transition. I've basically made an extended version of Titanium. (And i really should've looked at its source earlier, since it's really loving simple.)


My biggest thanks however go to Ninja Rope, since that is EXACTLY what i was looking for, and then some. :)

Mithaldu
Sep 25, 2007

Let's cuddle. :3:

Triple Tech posted:

Okay, now my real question. We've covered what. Now why. Why is this superior than traditional return's? I've not yet seen anything you couldn't do with just return.
Not an expert on this and have only read part of the article you linked (which is pretty darn neat), however my take on a useful example is this:

Tree-search. If you have to search through some tree recursively and are only looking for one single result, i'd gather you can do something like this:
1. Mark the point where you start searching.
2. Dive into tree.
3. Once you've got the result, jump back to the marked point with the result.

Compared with bubbling the result back up with returns, this could probably be faster. More importantly though it should be easier to implement with less code, since you don't need to return ANYTHING at all, and can thus also completely skip any sorts of checks on returns.

Mithaldu fucked around with this message at 07:27 on Jan 15, 2009

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
String comparison is done with eq or ne. Stuff like != only works on numbers. :)

http://perldoc.perl.org/perlop.html

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
If you want concurrency without using actual threads, you could try Coro.

Adbot
ADBOT LOVES YOU

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
I'm currently working on a cross-platform gui flashcard application that i'm thinking about adding to CPAN. Flashcard sets would be stored as individual modules.

However i'm also thinking about making it possible to link the items in the flashcard sets to audio bits, which would optimally be present in the form of audiobanks available as modules on cpan. As i'm doing this with wxPerl i have one restriction though: The audio bits need to be plain wav files and actually present as files; i can't simply feed them to Wx::Sound as a variable.

Right now i'm pondering though exactly how to accomplish this. The ways i can think of would be as follows:
- Have the audiobank module be a hash which contains serialized (Storable, FreezeThaw or something like that) versions of the audio files. When the sound files are required they are unserialized, dumped with File::Temp and the filename forwarded. Problem: Not very elegant.
- Simply add the .wavs as files to the module package and figure out the path to the files, then forward that. Problem: I have no idea if there is a module for that and i don't want to do it the brute way.

Do any of you have better ideas as to how to accomplish this or other comments? Maybe i'm thinking about it in the wrong way completely?

  • Locked thread