Используйте PDO
и подготовленные запросы.
($conn
- объект PDO
)
$stmt = $conn->prepare("INSERT INTO tbl VALUES(:id, :name)");
$stmt->bindValue(':id', $id);
$stmt->bindValue(':name', $name);
$stmt->execute();
Вы создаете выпуск или отладку?
При выполнении в режиме отладки, массив повышения мог бы быть действительно медленным, потому что их шаблонное волшебство не встраивается, правильно давая много издержек в вызовах функции. Я не уверен, как много массив реализован, хотя, таким образом, это могло бы быть полностью прочь:)
, Возможно, существует некоторое различие в порядке устройства хранения данных также, таким образом, у Вас мог бы быть сохраненный столбец своего изображения столбцом и записью его строка строкой. Это дало бы плохое поведение кэша и может замедлить вещи.
Попытка, переключающая порядок цикла X и Y и, видит, получаете ли Вы что-нибудь. Существует некоторая информация об устройстве хранения данных, заказывающем здесь: http://www.boost.org/doc/libs/1_37_0/libs/multi_array/doc/user.html
РЕДАКТИРОВАНИЕ: Так как Вы, кажется, используете двумерную матрицу для обработки изображений, Вы могли бы интересоваться проверкой библиотеки обработки изображений повышений gil.
Это могло бы иметь массивы с меньше служебным, который работает отлично на Вашу ситуацию.
Сборка в режиме выпуска, используйте objdump и посмотрите на блок. Они могут делать совершенно другие вещи, и Вы будете в состоянии видеть, какую оптимизацию компилятор использует.
Я думаю, что знаю то, что проблема..., возможно.
Для внедрения BOOST для имения синтаксиса как: матрица [x] [y]. это означает, что матрица [x] должна возвратить ссылку на объект, который действует как 1D массив столбец , на уровне которого ссылка точки [y] дает Вам Ваш элемент.
проблема здесь состоит в том, что Вы выполняете итерации в строка, крупнейшая порядок (который типичен в c/c ++, так как собственные массивы являются строкой главный IIRC. Компилятор должен повторно выполнить матрицу [x] для каждого y в этом случае. При итерации в столбце главного порядка при использовании матрицы повышения можно видеть лучшую производительность.
Просто теория.
РЕДАКТИРОВАНИЕ: в моей системе Linux (с некоторыми незначительными изменениями) я протестировал свою теорию и действительно показывал [приблизительно 111] повышение производительности путем переключения X и Y, но это было еще медленнее, чем собственный массив. Это могло бы быть простым выпуском компилятора, не бывшего способного оптимизировать далеко временный ссылочный тип.
Рассмотрите использование Блица ++ вместо этого. Я испытал Блиц, и его производительность на одном уровне с массивом C-стиля!
Выезд Ваш код с Блицем, добавленным ниже:
<час>#include <windows.h>
#define _SCL_SECURE_NO_WARNINGS
#define BOOST_DISABLE_ASSERTS
#include <boost/multi_array.hpp>
#include <blitz/array.h>
int main(int argc, char* argv[])
{
const int X_SIZE = 200;
const int Y_SIZE = 200;
const int ITERATIONS = 500;
unsigned int startTime = 0;
unsigned int endTime = 0;
// Create the boost array
typedef boost::multi_array<double, 2> ImageArrayType;
ImageArrayType boostMatrix(boost::extents[X_SIZE][Y_SIZE]);
//------------------Measure boost----------------------------------------------
startTime = ::GetTickCount();
for (int i = 0; i < ITERATIONS; ++i)
{
for (int y = 0; y < Y_SIZE; ++y)
{
for (int x = 0; x < X_SIZE; ++x)
{
boostMatrix[x][y] = 2.345;
}
}
}
endTime = ::GetTickCount();
printf("[Boost] Elapsed time: %6.3f seconds\n", (endTime - startTime) / 1000.0);
//------------------Measure blitz-----------------------------------------------
blitz::Array<double, 2> blitzArray( X_SIZE, Y_SIZE );
startTime = ::GetTickCount();
for (int i = 0; i < ITERATIONS; ++i)
{
for (int y = 0; y < Y_SIZE; ++y)
{
for (int x = 0; x < X_SIZE; ++x)
{
blitzArray(x,y) = 2.345;
}
}
}
endTime = ::GetTickCount();
printf("[Blitz] Elapsed time: %6.3f seconds\n", (endTime - startTime) / 1000.0);
//------------------Measure native-----------------------------------------------
// Create the native array
double *nativeMatrix = new double [X_SIZE * Y_SIZE];
startTime = ::GetTickCount();
for (int i = 0; i < ITERATIONS; ++i)
{
for (int y = 0; y < Y_SIZE; ++y)
{
for (int x = 0; x < X_SIZE; ++x)
{
nativeMatrix[x + (y * X_SIZE)] = 2.345;
}
}
}
endTime = ::GetTickCount();
printf("[Native]Elapsed time: %6.3f seconds\n", (endTime - startTime) / 1000.0);
return 0;
}
<час> Вот результат в отладке и выпуске.
ОТЛАДКА:
Boost 2.093 secs
Blitz 0.375 secs
Native 0.078 secs
ВЫПУСК:
Boost 0.266 secs
Blitz 0.016 secs
Native 0.015 secs
я использовал компилятор SP1 MSVC 2008 для этого.
мы можем теперь сказать до свидания массиву C-stlye? =p
Другая вещь попробовать состоит в том, чтобы использовать итераторы вместо прямого индекса для массива повышения.
Я задаюсь вопросом две вещи:
1) граничная проверка: определите макрос препроцессора BOOST_DISABLE_ASSERTS до включения multi_array.hpp в Вашем приложении. Это выключает связанную проверку. не уверенный, если это это, отключает, когда NDEBUG.
2) базисный индекс: MultiArray может индексировать массивы от оснований, отличающихся от 0. Это означает, что multi_array хранит основание системы счисления (в каждом размере) и использует более сложную формулу для получения точного местоположения в памяти, я задаюсь вопросом, является ли это все об этом.
Иначе я не понимаю, почему мультимассив должен быть медленнее, чем C-массивы.
Ваш тест испорчен.
то, Что Вы, вероятно, видите, является результатом Вашего оптимизирующего компилятора, видя, что большинство или весь Ваш "собственный массив" циклы могут быть удалены. То же теоретически верно для Вашего повышения:: циклы MultiArray, но MultiArray, вероятно, достаточно сложно для нанесения поражения оптимизатору.
Делают это небольшое изменение Вашего испытательного стенда , и Вы будете видеть больше реалистических результатов: Измените оба происшествия" = 2.345
"с" *= 2.345
"и скомпилируйте снова с оптимизацией. Это будет препятствовать тому, чтобы Ваш компилятор обнаружил, что внешний цикл каждого теста избыточен.
я сделал это и получил сравнение скорости ближе с 2:1.
На моей машине, используя
g++ -O3 -march=native -mtune=native --fast-math -DNDEBUG test.cpp -o test && ./test
, я получаю
[Boost] Elapsed time: 0.020 seconds
[Native]Elapsed time: 0.020 seconds
Однако, меняя const int ITERATIONS
на 5000
, я получаю
[Boost] Elapsed time: 0.240 seconds
[Native]Elapsed time: 0.180 seconds
и затем ITERATIONS
вернуться к 500
, но X_SIZE
и Y_SIZE
установить на 400
Я получаю гораздо более существенную разницу
[Boost] Elapsed time: 0.460 seconds
[Native]Elapsed time: 0.070 seconds
, наконец, инвертируя внутренний цикл для случая [Boost]
, чтобы он выглядел как
for (int x = 0; x < X_SIZE; ++x)
{
for (int y = 0; y < Y_SIZE; ++y)
{
и сохраняя ITERATIONS
, X_SIZE
и Y_SIZE
в 500
, 400
и 400
, я получаю
[Boost] Elapsed time: 0.060 seconds
[Native]Elapsed time: 0.080 seconds
Если я инвертирую Внутренний цикл также для случая [Native]
(так что в неправильном порядке для этого случая) я получаю, что неудивительно,
[Boost] Elapsed time: 0.070 seconds
[Native]Elapsed time: 0.450 seconds
Я использую gcc (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5
в Ubuntu 10.10
] Итак, в заключение:
Я ожидал бы, что мультимассив будет так же эффективен. Но я получаю подобные результаты на Mac PPC с помощью gcc. Я также попробовал multiarrayref, так, чтобы обе версии использовали то же устройство хранения данных без различия. Это хорошо для знания, так как я использую мультимассив в части моего кода, и просто предположил, что это было подобно кодированию руки.
Аналогичный вопрос был задан и дан ответ здесь:
http: // www.codeguru.com/forum/archive/index.php/t-300014.html
Короткий ответ заключается в том, что компилятору проще всего оптимизировать простые массивы, а не так просто оптимизировать версию Boost. Следовательно, конкретный компилятор может не дать версии Boost все те же преимущества оптимизации.
Компиляторы также могут различаться по тому, насколько хорошо они будут оптимизировать по сравнению с тем, насколько они будут консервативными (например, с шаблонным кодом или другими сложностями).
Я модифицировал приведенный выше код в визуальной студии 2008 v9.0.21022 и применил контейнерные подпрограммы из Numerical Recipe для C и C++
http://www.nrbook.com/nr3/, используя их лицензионные подпрограммы dmatrix и MatDoub соответственно
dmatrix использует устаревший синтаксический оператор malloc и не рекомендуется.... MatDoub использует команду New
Скорость в секундах в Release версии:
Boost: 0.437
Native: 0.032
Numerical Recipes C: 0.031
Numerical Recipes C: 0.031
So from the above blitz looks like the best free alternative.
Я тестировал на Snow Leopard Mac OS, используя gcc 4.2.1
Debug:
[Boost] Elapsed time: 2.268 seconds
[Native]Elapsed time: 0.076 seconds
Release:
[Boost] Elapsed time: 0.065 seconds
[Native]Elapsed time: 0.020 seconds
Вот код (измененный так, чтобы его можно было компилировать на Unix):
#define BOOST_DISABLE_ASSERTS
#include <boost/multi_array.hpp>
#include <ctime>
int main(int argc, char* argv[])
{
const int X_SIZE = 200;
const int Y_SIZE = 200;
const int ITERATIONS = 500;
unsigned int startTime = 0;
unsigned int endTime = 0;
// Create the boost array
typedef boost::multi_array<double, 2> ImageArrayType;
ImageArrayType boostMatrix(boost::extents[X_SIZE][Y_SIZE]);
// Create the native array
double *nativeMatrix = new double [X_SIZE * Y_SIZE];
//------------------Measure boost----------------------------------------------
startTime = clock();
for (int i = 0; i < ITERATIONS; ++i)
{
for (int y = 0; y < Y_SIZE; ++y)
{
for (int x = 0; x < X_SIZE; ++x)
{
boostMatrix[x][y] = 2.345;
}
}
}
endTime = clock();
printf("[Boost] Elapsed time: %6.3f seconds\n", (endTime - startTime) / (double)CLOCKS_PER_SEC);
//------------------Measure native-----------------------------------------------
startTime = clock();
for (int i = 0; i < ITERATIONS; ++i)
{
for (int y = 0; y < Y_SIZE; ++y)
{
for (int x = 0; x < X_SIZE; ++x)
{
nativeMatrix[x + (y * X_SIZE)] = 2.345;
}
}
}
endTime = clock();
printf("[Native]Elapsed time: %6.3f seconds\n", (endTime - startTime) / (double)CLOCKS_PER_SEC);
return 0;
}