PHOENIX -- Matt Cain had all four pitches working, was hitting his spots inside and out, had the hitters guessing.
The tired and free-swinging Arizona Diamondbacks never stood much of a chance.
Cain pitched eight sharp innings in a combined three-hitter and the San Francisco Giants took advantage of the weary Diamondbacks for a 3-0 win Thursday night.
"He was just on," Giants manager Bruce Bochy said. "And when Matt's on, he's tough. He had great stuff in the first inning and pounded the strike zone with quality strikes."
Andres Torres hit a solo homer off Rodrigo Lopez (5-9) and rookie Buster Posey extended his hitting streak to 16 games. The Giants had just four other hits, but didn't need many the way Cain (8-8) was pitching.
The right-hander one-hit Arizona on May 28 and was nearly as dominant the second time around against a Diamondbacks team coming off its longest game in nearly eight years.
Getting Arizona's hitters to bail on his big, overhand curveball and surprising them with his mid-90s fastball, Cain held the Diamondbacks to three hits in a ballpark that usually makes opposing pitchers want to skip a turn in the rotation.
"Found a good rhythm and was able to throw all four pitches for strikes," Cain said. "I was working both sides of the plate with my heater and those are the kind of days you want to take advantage of."
Brian Wilson pitched a perfect ninth for his 27th save in 29 chances and 13th straight to help the Giants (53-43) reach a season-high 10 games over .500 after their 13th win in 17 games.
Arizona didn't put up much of a fight after its 14-inning win over the Mets, flailing at pitches well out of the strike zone and getting just one runner past second base.
The Diamondbacks struck out 10 times after whiffing a franchise-record 16 times the night before and were shut out for the eighth time this season, wasting a solid effort from Lopez and putting the brakes on the momentum culled from a three-game sweep over New York.
"I had confidence going into tonight because we had a good series against the Mets [offensively]," Lopez said. "I felt that like if I kept my team in the game they would score a couple of runs. Unfortunately, it was not the case for us."
Cain didn't make it easy, striking out nine, including five straight midway through, and got some defensive help, too.
Torres made an against-the-wall catch in left to take extra bases away from Chris Young in the third inning, and first baseman Aubrey Huff looked as though he was catching flies (the bugs) barehanded with a quick-reacting snare of Miguel Montero's liner in the sixth.
Cain has pitched 17 scoreless innings against Arizona this season.
"Good stuff," Arizona manager Kirk Gibson said. "Late in the game, he really started mixing his secondary stuff in a lot more first pitch. He is a good pitcher. He has done that to a lot of people."
Lopez was nearly as good. Just not good enough.
A two-out walk hurt the right-hander in the first inning, with Huff coming around to score after a stolen base and Posey's single to center.
Lopez then left an 0-2 pitch at the letters in third inning to Torres and he hit it out to right-center for a solo shot that put the Giants up 2-0.
That's not much of a surprise, though.
Lopez leads the majors with 24 homers allowed, nine of those coming over his four July starts.
He didn't give up another long ball, but was knocked for another run in the seventh on Aaron Rowand's run-scoring single over a drawn-in infield that put the Giants up 3-0.
Lopez allowed three runs and five hits with seven strikeouts in seven innings for his third loss in four starts.
"Loppy threw well for us," Gibson said. "The Giants got two guys on with nobody out. They get them over and got them in. We didn't do that when we had the same opportunity."
Arizona 1B Adam LaRoche made two nifty defensive plays. He leaned over the rail to snare Freddy Sanchez's foul popup in the first inning and had an over-the-shoulder grab on another by Sanchez in the eighth. ... Posey has reached base safely in 20 straight games. ... Young stole base No. 20 in the first inning despite Cain catching him taking off too early.