By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
438,177 Members | 976 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 438,177 IT Pros & Developers. It's quick & easy.

Code to compare two libraries for cells and pins

P: 33
I am totally new to unix and perl. Although I have gone thtough some basics of both, I am still not quite comfortable with using them. I have received the following assignment. Can anyone pls help:

Cell : AND1
A1 A2 Y
Cell : INV1

Cell : AND1
Cell : INV2

expected o/p: <Lib1> <Lib2>
- INV1 missing in LIB2
- INV2 missing in LIB1
- AND1/A1 missing in LIB2
- AND1/A2 missing in LIB2
- AND1/A missing in LIB1
- AND1/A missing in LIB1

open Lib1
match for cell string : get cell name in a variable
match for pin names : $hash1{$cell}{$pin}=1;

open Lib2
match for cell string : get cell name in a variable
match for pin names : $hash2{$cell}{$pin}=1;

Iterate through hash1 and check is exists in hash2 or not. If not report missing...
Iterate through hash2 and check is exists in hash1 or not. If not report missing...

I shall be great full for any help on this.
Jan 28 '10 #1
Share this Question
Share on Google+
14 Replies

P: 33
somebody pleeeese help me!
Jan 29 '10 #2

P: 33
i have the following code pls somebody reply and tell my how i can use it. pleeeeeeeese!!

Expand|Select|Wrap|Line Numbers
  1. # read all of file1
  2. open(F,&quot;file1&quot;)||die;
  3. while(<F>){
  4.   $file1hash{$_}=1; # into a hash array
  5. }
  6. close(F);
  8. # create the output file
  9. open(OF,&quot;out.file&quot;)||die;
  10. # then read through file2
  11. open(F,&quot;file2&quot;)||die;
  12. while(<F>){
  13.   print OF $_ unless defined($file1hash{$_});
  14. }
  15. close(F);
Jan 29 '10 #3

Expert 100+
P: 785
Have you written this code yourself? If not, do you understand it?
Do you also understand the line "match for pin names : $hash1{$cell}{$pin}=1;" in your assignment? Can you program Perl and do you understand how to use hashes?
It seems not. (Please correct me if I guesssed wrong. Then read no further on). But if I am right, the best help I can give you is to google for a perl tutorial and execute it.
We are not here to make your homework or give you spoonfeed code (see forum guidelines), even if you are begging more than once.
But we will happily help you with your own code listed here.

So what is the problem with the code you listed ? You wrote, you don't know how to use it. So what does that mean? That you don't know how to run perl programs in general, or that you don't know what the code is doing? The latter one implies that you didn't write the code by yourself, but copied it from somewhere.

Here's more help:
To solve your task, you need following knowledge:
- how to run a perl program
- how to use arrays in perl (how to enumerate, assign and access elements)
- how to open files and read the content as string
- how to compare strings

Please do the corresponding tutorials and come back here with your own code you did after that.
Jan 29 '10 #4

P: 33
thank you so much for your reply.
i really appreciate the fact that you discourage spoon feeding and push for self attempt.
i am to do a project that requires some assistance of perl. i havent touched perl before and logged on to your forum to get some help that could get me started so as to speed up.
i know i can always invest time in tutorials and learn it my self. since this is also what you suggest i guess i will just have to bear with the delay and go for it!
well thanks a lot again!
Jan 30 '10 #5

P: 33

i have already potsed my assignment up there so u know what i have to do. i wonder if i could get any help with the following. i figured i could iterate through the hashes in two possible ways:

i can use use the for each loop like this:
Expand|Select|Wrap|Line Numbers
  1. foreach my $key ( keys %hash )
  2. {
  3.   print "key: $key, value: $hash{$key}\n";
  4. }
or i can use the while loop:
Expand|Select|Wrap|Line Numbers
  1. while ( ($key, $value) = each %hash )
  2. {
  3.   print "key: $key, value: $hash{$key}\n";
  4. }
but i can seem to figure which would optimize the solution.
pls help.

Feb 2 '10 #6

Expert 100+
P: 785
Hi, I was very busy so a quick answer, more tomorrow.
The second solution is not optimized, you should print $value instead of $hash{$key} so it doesn't do a timeconsuming search on the hash. You alread have the value, so just print it, why search again for it?
If you change it this way, the second loop should be faster, especially on big hash-tables.

if you don't need the value, but only the key, the first solution should be faster.

This is a strong guess from my experience, I haven't done any performance checks to verify this.
Feb 3 '10 #7

Expert Mod 100+
P: 589
Benchmark - benchmark running times of Perl code

If you run a benchmark test, I think you'll fine that the foreach loop is about 30% faster. But unless you're working with very large hashes, the difference will be within a few millionths to a few thousandths of a second
Feb 3 '10 #8

P: 33
Thank you for that...
i will get back once i try something.
however you said there will be more tomorrow, so i shall be waiting!
Thanks again
Feb 4 '10 #9

Expert 100+
P: 785
Ron, you are right. It seems that the search for a value inside a hash array by key isn't the bottleneck, it only makes it 7% slower. But why is it so much slower then?

I tested with the benchmark you gave, here are the results:
Expand|Select|Wrap|Line Numbers
  1.                  Rate  test_while_hash  test_while  test_foreach
  2. test_while_hash 1228/s          --           -6%        -43%
  3. test_while      1314/s          7%            --        -40%
  4. test_foreach    2172/s         77%           65%          --
My program:
Expand|Select|Wrap|Line Numbers
  1. use Benchmark qw(:all);
  3. sub test_foreach {
  4.     my $key, $message;
  5.     foreach $key ( keys %hash ) 
  6.     { 
  7.         $message = "key: $key, value: $hash{$key}\n";
  8.         # print $message;
  9.     } 
  10. };
  12. sub test_while {
  13.     my $key, $value, $message;
  14.     while ( ($key, $value) = each %hash ) 
  15.     { 
  16.         $message = "key: $key, value: $value\n"; 
  17.         # print $message;
  18.     } 
  19. };
  21. sub test_while_hash {
  22.     my $key, $value, $message;
  23.     while ( ($key, $value) = each %hash ) 
  24.     { 
  25.         $message = "key: $key, value: $hash{$key}\n";
  26.         # print $message;
  27.     } 
  28. };
  30. # main program
  31. our %hash;
  32. foreach my $number (1..1000) {
  33.     $hash{"number$number" } = $number;
  34. }
  35. cmpthese(-1, {
  36.   'test_foreach' => \&test_foreach,
  37.   'test_while' => \&test_while,
  38.   'test_while_hash' => \&test_while_hash,
  39. });
Remarks for OP:
This program generates an array of 1000 hash-values
%hash=("number1" => 1, "number2" => 2, "number3" => 3);
and so on. Then it runs each of the subs "test_foreach", "test_while", "test_while_hash" until 1 second is over and counts how many times it was run. This value is shown as "Rate" in the statistics.
Feb 4 '10 #10

Expert Mod 100+
P: 589
First, your code is missing
Expand|Select|Wrap|Line Numbers
  1. use warnings;
  2. use strict;
If it were, you'd be getting several warnings and a number of compilation errors ending with "aborted due to compilation errors".

It is very important to include those pragmas in all scripts, including examples posted here.

The issue here is that the test that perl does at the start of each iteration of a while loop has more overhead than what is done when iterating over a list via for/foreach.

The precise details of that overhead is unknown to me, but you could probably find out some of those details by running it through strace. There are several CPAN modules that will show what's going on under the hood, but I haven't used them and don't recall their names.
Feb 4 '10 #11

Expert Mod 100+
P: 589
I forgot to mention that the system specs and current load will impact the benchmark results. When I ran the test on my Windows box, I received roughly the same results as yours, but my fedora box was quite different.

Here's a corrected version and the results.
Expand|Select|Wrap|Line Numbers
  1. [root@rkb-2 ~]# cat
  2. #!/usr/bin/perl
  4. use warnings;
  5. use strict;
  6. use Benchmark qw( cmpthese );
  8. my %hash;
  9. foreach my $number (1..1000) {
  10.     $hash{"number$number" } = $number;
  11. }
  13. cmpthese(-10, {
  14.   'test_foreach'    => \&test_foreach,
  15.   'test_while'      => \&test_while,
  16.   'test_while_hash' => \&test_while_hash,
  17. });
  20. sub test_foreach {
  21.     foreach my $key ( keys %hash ) {
  22.         my $message = "key: $key, value: $hash{$key}\n";
  23.     }
  24. };
  26. sub test_while {
  27.     while ( my ($key, $value) = each %hash ) {
  28.         my $message = "key: $key, value: $value\n";
  29.     }
  30. };
  32. sub test_while_hash {
  33.     while ( my ($key, $value) = each %hash ) {
  34.         my $message = "key: $key, value: $hash{$key}\n";
  35.     }
  36. };
Expand|Select|Wrap|Line Numbers
  1. [root@rkb-2 ~]# ./
  2.                  Rate test_while_hash      test_while    test_foreach
  3. test_while_hash 223/s              --             -9%            -23%
  4. test_while      244/s             10%              --            -16%
  5. test_foreach    290/s             30%             19%              --
Feb 4 '10 #12

Expert 100+
P: 785
I tested on a Sun Solaris Sparc Workstation, and got roughly the same performance results Ron got. That means the differences are not so big on Unix machines than on Windows machines.
I figured out that defining the variables with "my" before the loop is faster than defining them when they are used (although the latter one is better programming style regarding the usage scope of the variable).
Here the test "test_foreach" ran 13% faster than "test_foreach2".
Expand|Select|Wrap|Line Numbers
  1. sub test_foreach {
  2.     my ($key, $message);
  3.     foreach $key ( keys %hash ) 
  4.     { 
  5.         $message = "key: $key, value: $hash{$key}\n";
  6.      } 
  7. };
  8. sub test_foreach2 {
  9.     foreach my $key ( keys %hash ) 
  10.     { 
  11.         my $message = "key: $key, value: $hash{$key}\n";
  12.     } 
  13. };
This is just a code snipped.
Of course I put "use strict; use warnings;" at the begin of my file.

Perl-versions used:
Windows: perl v5.10.0
Solaris: perl v5.8.4
Feb 5 '10 #13

Expert 100+
P: 785
Let's get back to the OP's (BlackGoat) assignment.
Because BlackGoat doesn't give up and starts programming of his own, which is a very good character trait, I want to give him a quickstart with some code snippets:
You need following algorhithm:
  1. read in from file, line by line:
    Expand|Select|Wrap|Line Numbers
    1. open(FILE, "Lib1.txt") or die "Error";
    2. while(defined(my $line = <FILE>)) { print $line};
    3. close(FILE);
  2. If the line starts with "cell :" then you know a name for a "cell" is following, else parse the line and split it into words (delimiter: space) to get all names for the "pins" of the current "cell". You can do that with the perl-function split() and some string comparisons.
  3. store the words read in into a two-dimensional array $hash1{"cell_name"}{"pin_name"}, which is a hash of hashes. Here is how I stored a "pin":
    As you can see in the code below, in the outer hashtable, each key is a name of the "cell" and each value points to an inner hashtable that contains all the "pins" of this "cell". The keys of the inner hashes are the names of the "pins" and the values are counter values, that means how many times this name occurred.
    This code snippet shows how to make such a hash and how to access or add its elements:
    Expand|Select|Wrap|Line Numbers
    1. # definition of hash of hashes
    2. my %hash1 = ("AND1" => {"A1" => 1, "A2" => 1, "Y" => 1}, "INV1" => {"A" => 1, "Z" => 1});
    3. # ways to access and add new elements
    4. print "Cell AND1, pin A1=".$hash1{"AND1"}{"A1"}."\n";
    5. $hash1{"INV1"}{"Z"} = 3;
    6. print "Cell INV1, pin Z=".$hash1{"INV1"}{"Z"}."\n";
    7. $hash1{"NEW"} = {"X" => 4};
    8. print "Cell NEW, pin X=".$hash1{"NEW"}{"X"}."\n";
    9. print "Cell NEW, pin Y=".$hash1{"NEW"}{"Y"}."\n";
    10. $hash1{"NEW"}{"Y"} = 7;
    11. print "Cell NEW, pin Y=".$hash1{"NEW"}{"Y"}."\n";
    This code snippet produces following output
    Expand|Select|Wrap|Line Numbers
    1. Cell AND1, pin A1=1
    2. Cell INV1, pin Z=3
    3. Cell NEW, pin X=4
    4. Use of uninitialized value in concatenation (.) or string at line 17.
    6. Cell NEW, pin Y=
    7. Cell NEW, pin Y=7
  4. do the same with the second file: read in all words and store them in $hash2{"cell_name"}{"pin_name"}
  5. after all is read in, you need to compare all keys of both hash1 and hash2 and print out the differences (One outside-loop to go throgh all cells and one inside-loop to go through all pins of a cell).
Feb 5 '10 #14

P: 33
Thanks for helping out Sir.
Feb 8 '10 #15

Post your reply

Sign in to post your reply or Sign up for a free account.